diff --git a/src/renderer/api/kube-watch-api.ts b/src/renderer/api/kube-watch-api.ts index ee6c9202a1..b736616aa0 100644 --- a/src/renderer/api/kube-watch-api.ts +++ b/src/renderer/api/kube-watch-api.ts @@ -22,8 +22,8 @@ export interface IKubeWatchMessage { } export interface IKubeWatchSubscribeStoreOptions { - autoLoad?: boolean; - waitUntilLoaded?: boolean; + preload?: boolean; // preload store items, default: true + waitUntilLoaded?: boolean; // subscribe only after loading all stores, default: true } export interface IKubeWatchLog { @@ -79,32 +79,41 @@ export class KubeWatchApi { }; } - async subscribeStores(stores: KubeObjectStore[], options: IKubeWatchSubscribeStoreOptions = {}): Promise<() => void> { - this.log({ - message: "Subscribing to stores", - meta: { stores, options }, - }); - - const { autoLoad = true, waitUntilLoaded = true } = options; + subscribeStores(stores: KubeObjectStore[], options: IKubeWatchSubscribeStoreOptions = {}): () => void { + const { preload = true, waitUntilLoaded = true } = options; const loading: Promise[] = []; + const disposers: Function[] = []; + let isDisposed = false; - if (autoLoad) { + async function subscribe() { + if (isDisposed) return; + const unsubscribeList = await Promise.all(stores.map(store => store.subscribe())); + disposers.push(...unsubscribeList); + if (isDisposed) unsubscribe(); + } + + function unsubscribe() { + isDisposed = true; + disposers.forEach(dispose => dispose()); + disposers.length = 0; + } + + if (preload) { loading.push(...stores.map(store => store.loadAll())); } if (waitUntilLoaded) { - try { - await Promise.all(loading); - } catch (error) { + Promise.all(loading).then(subscribe, error => { this.log({ message: new Error("Loading stores has failed"), meta: { stores, error, options }, - }) - } + }); + }); + } else { + subscribe(); } - const disposers = await Promise.all(stores.map(store => store.subscribe())); - return () => disposers.forEach(dispose => dispose()); // unsubscribe + return unsubscribe; } protected async resolveCluster(): Promise { diff --git a/src/renderer/components/+cluster/cluster-overview.tsx b/src/renderer/components/+cluster/cluster-overview.tsx index 74e6068e56..a2ef7077f1 100644 --- a/src/renderer/components/+cluster/cluster-overview.tsx +++ b/src/renderer/components/+cluster/cluster-overview.tsx @@ -24,12 +24,12 @@ export class ClusterOverview extends React.Component { getHostedCluster().available && clusterOverviewStore.loadMetrics(); } - async componentDidMount() { + componentDidMount() { this.metricPoller.start(true); disposeOnUnmount(this, [ - await kubeWatchApi.subscribeStores([nodesStore, podsStore, eventStore], { - autoLoad: true, + kubeWatchApi.subscribeStores([nodesStore, podsStore, eventStore], { + preload: true, }), reaction( () => clusterOverviewStore.metricNodeRole, // Toggle Master/Worker node switcher diff --git a/src/renderer/components/+namespaces/namespace-select.tsx b/src/renderer/components/+namespaces/namespace-select.tsx index d4656659a0..4dd21b53d3 100644 --- a/src/renderer/components/+namespaces/namespace-select.tsx +++ b/src/renderer/components/+namespaces/namespace-select.tsx @@ -9,6 +9,7 @@ import { Icon } from "../icon"; import { namespaceStore } from "./namespace.store"; import { FilterIcon } from "../item-object-list/filter-icon"; import { FilterType } from "../item-object-list/page-filters.store"; +import { kubeWatchApi } from "../../api/kube-watch-api"; interface Props extends SelectProps { showIcons?: boolean; @@ -29,12 +30,11 @@ const defaultProps: Partial = { export class NamespaceSelect extends React.Component { static defaultProps = defaultProps as object; - async componentDidMount() { - if (!namespaceStore.isLoaded) { - await namespaceStore.loadAll(); - } + componentDidMount() { disposeOnUnmount(this, [ - await namespaceStore.subscribe(), + kubeWatchApi.subscribeStores([namespaceStore], { + preload: !namespaceStore.isLoaded, + }) ]); } diff --git a/src/renderer/components/+network-services/service-details.tsx b/src/renderer/components/+network-services/service-details.tsx index 695ff2785a..3cc4a10e39 100644 --- a/src/renderer/components/+network-services/service-details.tsx +++ b/src/renderer/components/+network-services/service-details.tsx @@ -12,18 +12,18 @@ import { ServicePortComponent } from "./service-port-component"; import { endpointStore } from "../+network-endpoints/endpoints.store"; import { ServiceDetailsEndpoint } from "./service-details-endpoint"; import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; +import { kubeWatchApi } from "../../api/kube-watch-api"; interface Props extends KubeObjectDetailsProps { } @observer export class ServiceDetails extends React.Component { - async componentDidMount() { - if (!endpointStore.isLoaded) { - endpointStore.loadAll(); - } + componentDidMount() { disposeOnUnmount(this, [ - await endpointStore.subscribe(), + kubeWatchApi.subscribeStores([endpointStore], { + preload: !endpointStore.isLoaded, + }), ]); } diff --git a/src/renderer/components/+workloads-overview/overview.tsx b/src/renderer/components/+workloads-overview/overview.tsx index ad1b64b0a0..093882ea48 100644 --- a/src/renderer/components/+workloads-overview/overview.tsx +++ b/src/renderer/components/+workloads-overview/overview.tsx @@ -26,13 +26,14 @@ export class WorkloadsOverview extends React.Component { @observable isLoading = false; @observable isUnmounting = false; - async componentDidMount() { + componentDidMount() { disposeOnUnmount(this, [ - await kubeWatchApi.subscribeStores([ - podsStore, deploymentStore, daemonSetStore, - statefulSetStore, replicaSetStore, + kubeWatchApi.subscribeStores([ + podsStore, deploymentStore, daemonSetStore, statefulSetStore, replicaSetStore, jobStore, cronJobStore, eventStore, - ]) + ], { + preload: true, + }), ]); // fixme: reload stores diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 7a431771b4..a2aa0c8efe 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -76,17 +76,14 @@ export class App extends React.Component { whatInput.ask(); // Start to monitor user input device } - async componentDidMount() { - const cluster = getHostedCluster(); - + componentDidMount() { disposeOnUnmount(this, [ - await kubeWatchApi.subscribeStores([podsStore, nodesStore, eventStore], { - autoLoad: true, - waitUntilLoaded: true, + kubeWatchApi.subscribeStores([podsStore, nodesStore, eventStore], { + preload: true, }), reaction(() => this.warningsCount, (count) => { - broadcastMessage(`cluster-warning-event-count:${cluster.id}`, count); + broadcastMessage(`cluster-warning-event-count:${getHostedCluster().id}`, count); }), ]); } diff --git a/src/renderer/components/kube-object/kube-object-list-layout.tsx b/src/renderer/components/kube-object/kube-object-list-layout.tsx index 136e47099d..dab6137ca0 100644 --- a/src/renderer/components/kube-object/kube-object-list-layout.tsx +++ b/src/renderer/components/kube-object/kube-object-list-layout.tsx @@ -20,12 +20,14 @@ export class KubeObjectListLayout extends React.Component