From 1dc98a7dd9c59b14e03f4540229fbfa74fcfae5d Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Thu, 9 Mar 2023 08:55:27 -0500 Subject: [PATCH] Optimize Deployment workloads status computation Signed-off-by: Sebastian Malton --- .../statuses.injectable.ts | 53 +++++++++++++++++++ .../total-count.injectable.ts | 18 +++++++ .../deployments-workload.injectable.ts | 40 +++++--------- 3 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 packages/core/src/renderer/components/+workloads-deployments/statuses.injectable.ts create mode 100644 packages/core/src/renderer/components/+workloads-deployments/total-count.injectable.ts diff --git a/packages/core/src/renderer/components/+workloads-deployments/statuses.injectable.ts b/packages/core/src/renderer/components/+workloads-deployments/statuses.injectable.ts new file mode 100644 index 0000000000..ebdcb883e5 --- /dev/null +++ b/packages/core/src/renderer/components/+workloads-deployments/statuses.injectable.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import podStoreInjectable from "../+workloads-pods/store.injectable"; +import type { Deployment, PodStatusPhase } from "../../../common/k8s-api/endpoints"; +import { byLabels } from "../../../common/k8s-api/kube-object.store"; +import { getOrInsert } from "../../utils"; +import { foldPodStatusPhase } from "../../utils/fold-pod-status-phase"; +import deploymentStoreInjectable from "./store.injectable"; + +const statusCountsForAllDeploymentsInSelectedNamespacesInjectable = getInjectable({ + id: "status-counts-for-all-deployments-in-selected-namespaces", + instantiate: (di) => { + const deploymentStore = di.inject(deploymentStoreInjectable); + const podStore = di.inject(podStoreInjectable); + + return computed(() => { + const statuses = { running: 0, failed: 0, pending: 0 }; + const podsByNamespace = new Map> }; status: PodStatusPhase }[]>(); + + for (const pod of podStore.items) { + getOrInsert(podsByNamespace, pod.getNs(), []).push({ + metadata: { + labels: JSON.parse(JSON.stringify(pod.metadata.labels ?? {})), + }, + status: pod.getStatus(), + }); + } + + const getChildPods = (deployment: Deployment) => { + const pods = podsByNamespace.get(deployment.getNs()) ?? []; + + return pods.filter(byLabels(deployment.spec.template.metadata.labels)); + }; + + for (const deployment of deploymentStore.contextItems) { + const status = getChildPods(deployment) + .map(pod => pod.status) + .reduce(foldPodStatusPhase, "running"); + + statuses[status]++; + } + + return statuses; + }); + }, +}); + +export default statusCountsForAllDeploymentsInSelectedNamespacesInjectable; + diff --git a/packages/core/src/renderer/components/+workloads-deployments/total-count.injectable.ts b/packages/core/src/renderer/components/+workloads-deployments/total-count.injectable.ts new file mode 100644 index 0000000000..93c94dbd40 --- /dev/null +++ b/packages/core/src/renderer/components/+workloads-deployments/total-count.injectable.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { computed } from "mobx"; +import deploymentStoreInjectable from "./store.injectable"; + +const totalCountOfDeploymentsInSelectedNamespacesInjectable = getInjectable({ + id: "total-count-of-deployments-in-selected-namespaces", + instantiate: (di) => { + const deploymentStore = di.inject(deploymentStoreInjectable); + + return computed(() => deploymentStore.getTotalCount()); + }, +}); + +export default totalCountOfDeploymentsInSelectedNamespacesInjectable; diff --git a/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts b/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts index b41e4ea5ca..3702886dd4 100644 --- a/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/deployments-workload.injectable.ts @@ -5,38 +5,24 @@ import { getInjectable } from "@ogre-tools/injectable"; import { workloadInjectionToken } from "../workload-injection-token"; import { ResourceNames } from "../../../../utils/rbac"; -import namespaceStoreInjectable from "../../../+namespaces/store.injectable"; -import deploymentsStoreInjectable from "../../../+workloads-deployments/store.injectable"; import navigateToDeploymentsInjectable from "../../../../../common/front-end-routing/routes/cluster/workloads/deployments/navigate-to-deployments.injectable"; -import { computed } from "mobx"; +import totalCountOfDeploymentsInSelectedNamespacesInjectable from "../../../+workloads-deployments/total-count.injectable"; +import statusCountsForAllDeploymentsInSelectedNamespacesInjectable from "../../../+workloads-deployments/statuses.injectable"; const deploymentsWorkloadInjectable = getInjectable({ id: "deployments-workload", - instantiate: (di) => { - const navigate = di.inject(navigateToDeploymentsInjectable); - const namespaceStore = di.inject(namespaceStoreInjectable); - const store = di.inject(deploymentsStoreInjectable); - - return { - resource: { - apiName: "deployments", - group: "apps", - }, - open: navigate, - - amountOfItems: computed( - () => store.getAllByNs(namespaceStore.contextNamespaces).length, - ), - - status: computed(() => - store.getStatuses(store.getAllByNs(namespaceStore.contextNamespaces)), - ), - - title: ResourceNames.deployments, - orderNumber: 20, - }; - }, + instantiate: (di) => ({ + resource: { + apiName: "deployments", + group: "apps", + }, + open: di.inject(navigateToDeploymentsInjectable), + amountOfItems: di.inject(totalCountOfDeploymentsInSelectedNamespacesInjectable), + status: di.inject(statusCountsForAllDeploymentsInSelectedNamespacesInjectable), + title: ResourceNames.deployments, + orderNumber: 20, + }), injectionToken: workloadInjectionToken, });