diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index 0620356e9a..1792fb953b 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -1,5 +1,6 @@ import "../common/cluster-ipc"; import type http from "http" +import { ipcMain } from "electron" import { autorun } from "mobx"; import { clusterStore, getClusterIdFromHost } from "../common/cluster-store" import { Cluster } from "./cluster" @@ -30,6 +31,29 @@ export class ClusterManager { }, { delay: 250 }); + + ipcMain.on("network:offline", () => { this.onNetworkOffline() }) + ipcMain.on("network:online", () => { this.onNetworkOnline() }) + } + + protected onNetworkOffline() { + logger.info("[CLUSTER-MANAGER]: network is offline") + clusterStore.enabledClustersList.forEach((cluster) => { + if (!cluster.disconnected) { + cluster.online = false + cluster.accessible = false + cluster.refreshConnectionStatus().catch((e) => e) + } + }) + } + + protected onNetworkOnline() { + logger.info("[CLUSTER-MANAGER]: network is online") + clusterStore.enabledClustersList.forEach((cluster) => { + if (!cluster.disconnected) { + cluster.refreshConnectionStatus().catch((e) => e) + } + }) } stop() { diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 57b9e219c3..656ee67cdb 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -67,12 +67,12 @@ export class Cluster implements ClusterModel, ClusterState { @observable kubeConfigPath: string; @observable apiUrl: string; // cluster server url @observable kubeProxyUrl: string; // lens-proxy to kube-api url - @observable enabled = false; - @observable online = false; - @observable accessible = false; - @observable ready = false; + @observable enabled = false; // only enabled clusters are visible to users + @observable online = false; // describes if we can detect that cluster is online + @observable accessible = false; // if user is able to access cluster resources + @observable ready = false; // cluster is in usable state @observable reconnecting = false; - @observable disconnected = true; + @observable disconnected = true; // false if user has selected to connect @observable failureReason: string; @observable isAdmin = false; @observable eventCount = 0; @@ -127,16 +127,16 @@ export class Cluster implements ClusterModel, ClusterState { } protected bindEvents() { - logger.info(`[CLUSTER]: bind events`, this.getMeta()); - const refreshTimer = setInterval(() => !this.disconnected && this.refresh(), 30000); // every 30s - const refreshMetadataTimer = setInterval(() => !this.disconnected && this.refreshMetadata(), 900000); // every 15 minutes + logger.info(`[CLUSTER]: bind events`, this.getMeta()) + const refreshTimer = setInterval(() => !this.disconnected && this.refresh(), 30000) // every 30s + const refreshMetadataTimer = setInterval(() => !this.disconnected && this.refreshMetadata(), 900000) // every 15 minutes if (ipcMain) { this.eventDisposers.push( reaction(() => this.getState(), () => this.pushState()), () => { - clearInterval(refreshTimer); - clearInterval(refreshMetadataTimer); + clearInterval(refreshTimer) + clearInterval(refreshMetadataTimer) }, ); } diff --git a/src/renderer/api/kube-watch-api.ts b/src/renderer/api/kube-watch-api.ts index 464b785dfb..56c3fc1c86 100644 --- a/src/renderer/api/kube-watch-api.ts +++ b/src/renderer/api/kube-watch-api.ts @@ -109,17 +109,22 @@ export class KubeWatchApi { } } - protected async onRouteEvent({ type, url }: IKubeWatchRouteEvent) { - if (type === "STREAM_END") { + protected async onRouteEvent(event: IKubeWatchRouteEvent) { + if (event.type === "STREAM_END") { this.disconnect(); - const { apiBase, namespace } = KubeApi.parseApi(url); + const { apiBase, namespace } = KubeApi.parseApi(event.url); const api = apiManager.getApi(apiBase); if (api) { try { await api.refreshResourceVersion({ namespace }); this.reconnect(); } catch (error) { - console.debug("failed to refresh resource version", error) + console.error("failed to refresh resource version", error) + if (this.subscribers.size > 0) { + setTimeout(() => { + this.onRouteEvent(event) + }, 1000) + } } } } diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 6bedad727d..5ad908a528 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -54,6 +54,9 @@ export class App extends React.Component { appEventBus.emit({name: "cluster", action: "open", params: { clusterId: clusterId }}) + window.addEventListener("online", () => { + window.location.reload() + }) } get startURL() { diff --git a/src/renderer/lens-app.tsx b/src/renderer/lens-app.tsx index e6c2baa6c2..5c1b27b13a 100644 --- a/src/renderer/lens-app.tsx +++ b/src/renderer/lens-app.tsx @@ -1,5 +1,6 @@ import "../common/system-ca" import React from "react"; +import { ipcRenderer } from "electron"; import { Route, Router, Switch } from "react-router"; import { observer } from "mobx-react"; import { userStore } from "../common/user-store"; @@ -17,6 +18,12 @@ import { extensionLoader } from "../extensions/extension-loader"; export class LensApp extends React.Component { static async init() { extensionLoader.loadOnClusterManagerRenderer(); + window.addEventListener("offline", () => { + ipcRenderer.send("network:offline") + }) + window.addEventListener("online", () => { + ipcRenderer.send("network:online") + }) } render() {