1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

auto-reconnect on online/offline status change, interval connection check

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-01-25 14:52:22 +02:00
parent 632e77b263
commit 14a0c9cdca

View File

@ -40,15 +40,34 @@ export class KubeWatchApi {
private namespaceStore: NamespaceStore; private namespaceStore: NamespaceStore;
private requestId = 0; private requestId = 0;
private isConnected = false;
private reader: ReadableStreamReader<string>; private reader: ReadableStreamReader<string>;
private subscribers = observable.map<KubeApi, number>(); private subscribers = observable.map<KubeApi, number>();
private splitter = "\n";
private reconnectTimeoutMs = 5000;
private maxReconnectsOnError = 10;
// events // events
public onMessage = new EventEmitter<[IKubeWatchMessage]>(); public onMessage = new EventEmitter<[IKubeWatchMessage]>();
@computed get isActive(): boolean {
return this.apis.length > 0;
}
@computed get apis(): string[] {
const { cluster, namespaceStore } = this;
const activeApis = Array.from(this.subscribers.keys());
return activeApis.map(api => {
if (!cluster.isAllowedResource(api.kind)) {
return [];
}
if (api.isNamespaced) {
return namespaceStore.getContextNamespaces().map(namespace => api.getWatchUrl(namespace));
} else {
return api.getWatchUrl();
}
}).flat();
}
constructor() { constructor() {
this.init(); this.init();
} }
@ -67,27 +86,14 @@ export class KubeWatchApi {
private bindAutoConnect() { private bindAutoConnect() {
const connect = debounce(() => this.connect(), 1000); const connect = debounce(() => this.connect(), 1000);
return reaction(() => this.activeApis, connect, { reaction(() => this.apis, connect, {
fireImmediately: true, fireImmediately: true,
equals: comparer.structural, equals: comparer.structural,
}); });
}
@computed get activeApis(): string[] { window.addEventListener("online", () => this.connect());
const { cluster, namespaceStore } = this; window.addEventListener("offline", () => this.disconnect());
const activeApis = Array.from(this.subscribers.keys()); setInterval(() => this.connectionCheck(), 30000);
return activeApis.map(api => {
if (!cluster.isAllowedResource(api.kind)) {
return [];
}
if (api.isNamespaced) {
return namespaceStore.getContextNamespaces().map(namespace => api.getWatchUrl(namespace));
} else {
return api.getWatchUrl();
}
}).flat();
} }
getSubscribersCount(api: KubeApi) { getSubscribersCount(api: KubeApi) {
@ -149,10 +155,18 @@ export class KubeWatchApi {
return unsubscribe; return unsubscribe;
} }
protected async connect(apis = this.activeApis) { protected connectionCheck() {
if (this.isConnected) return;
return this.connect();
}
protected async connect(apis = this.apis) {
this.disconnect(); // close active connections first this.disconnect(); // close active connections first
if (!apis.length) { if (!navigator.onLine || !apis.length) {
this.isConnected = false;
return; return;
} }
@ -185,6 +199,7 @@ export class KubeWatchApi {
const stream = request.body.pipeThrough(new TextDecoderStream()); const stream = request.body.pipeThrough(new TextDecoderStream());
const reader = stream.getReader(); const reader = stream.getReader();
this.isConnected = true;
this.reader = reader; this.reader = reader;
while (true) { while (true) {
@ -192,18 +207,21 @@ export class KubeWatchApi {
if (done) break; // exit if (done) break; // exit
const events = (jsonBuffer + value).split(this.splitter); const events = (jsonBuffer + value).split("\n");
jsonBuffer = this.processBuffer(events); jsonBuffer = this.processBuffer(events);
} }
} catch (error) { } catch (error) {
this.log({ message: error }); this.log({ message: error });
} finally {
this.isConnected = false;
} }
} }
protected disconnect() { protected disconnect() {
this.reader?.cancel(); this.reader?.cancel();
this.reader = null; this.reader = null;
this.isConnected = false;
} }
// process received stream events, returns unprocessed buffer chunk if any // process received stream events, returns unprocessed buffer chunk if any
@ -272,14 +290,12 @@ export class KubeWatchApi {
this.connect(); this.connect();
} catch (error) { } catch (error) {
this.log({ this.log({
message: new Error("Failed to reconnect on stream end"), message: new Error(`Failed to connect on single stream end: ${error}`),
meta: { error, event }, meta: { event, error },
}); });
if (this.subscribers.size > 0) { if (this.isActive) {
setTimeout(() => { setTimeout(() => this.onServerStreamEnd(event), 1000);
this.onServerStreamEnd(event);
}, 1000);
} }
} }
} }