From 5994ef748c56c2a14f6d86fe3440b56a1374fdac Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Thu, 9 Mar 2023 08:46:52 -0500 Subject: [PATCH] Optimize ReplicaSet workloads status computation Signed-off-by: Sebastian Malton --- .../replicasets-workload.injectable.ts | 35 +++++-------- .../statuses.injectable.ts | 49 +++++++++++++++++++ .../total-count.injectable.ts | 18 +++++++ .../renderer/utils/fold-pod-status-phase.ts | 18 +++++++ 4 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 packages/core/src/renderer/components/+workloads-replicasets/statuses.injectable.ts create mode 100644 packages/core/src/renderer/components/+workloads-replicasets/total-count.injectable.ts create mode 100644 packages/core/src/renderer/utils/fold-pod-status-phase.ts diff --git a/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts b/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts index 3befeeafed..6efaa40efe 100644 --- a/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts +++ b/packages/core/src/renderer/components/+workloads-overview/workloads/implementations/replicasets-workload.injectable.ts @@ -5,33 +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 replicasetsStoreInjectable from "../../../+workloads-replicasets/store.injectable"; -import { computed } from "mobx"; import navigateToReplicasetsInjectable from "../../../../../common/front-end-routing/routes/cluster/workloads/replicasets/navigate-to-replicasets.injectable"; +import statusCountsForAllReplicaSetsInSelectedNamespacesInjectable from "../../../+workloads-replicasets/statuses.injectable"; +import totalCountOfReplicaSetsInSelectedNamespacesInjectable from "../../../+workloads-replicasets/total-count.injectable"; const replicasetsWorkloadInjectable = getInjectable({ id: "replicasets-workload", - instantiate: (di) => { - const navigate = di.inject(navigateToReplicasetsInjectable); - const namespaceStore = di.inject(namespaceStoreInjectable); - const store = di.inject(replicasetsStoreInjectable); - - return { - resource: { - apiName: "replicasets", - group: "apps", - }, - open: navigate, - amountOfItems: computed(() => store.getTotalCount()), - status: computed(() => - store.getStatuses(store.getAllByNs(namespaceStore.contextNamespaces)), - ), - title: ResourceNames.replicasets, - orderNumber: 50, - }; - }, + instantiate: (di) => ({ + resource: { + apiName: "replicasets", + group: "apps", + }, + open: di.inject(navigateToReplicasetsInjectable), + amountOfItems: di.inject(totalCountOfReplicaSetsInSelectedNamespacesInjectable), + status: di.inject(statusCountsForAllReplicaSetsInSelectedNamespacesInjectable), + title: ResourceNames.replicasets, + orderNumber: 50, + }), injectionToken: workloadInjectionToken, }); diff --git a/packages/core/src/renderer/components/+workloads-replicasets/statuses.injectable.ts b/packages/core/src/renderer/components/+workloads-replicasets/statuses.injectable.ts new file mode 100644 index 0000000000..20c8800878 --- /dev/null +++ b/packages/core/src/renderer/components/+workloads-replicasets/statuses.injectable.ts @@ -0,0 +1,49 @@ +/** + * 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 { PodStatusPhase } from "../../../common/k8s-api/endpoints"; +import { getOrInsert } from "../../utils"; +import { foldPodStatusPhase } from "../../utils/fold-pod-status-phase"; +import replicaSetStoreInjectable from "./store.injectable"; + +interface PodData { + status: PodStatusPhase; +} + +const statusCountsForAllReplicaSetsInSelectedNamespacesInjectable = getInjectable({ + id: "status-counts-for-all-replica-sets-in-selected-namespaces", + instantiate: (di) => { + const podStore = di.inject(podStoreInjectable); + const replicaSetStore = di.inject(replicaSetStoreInjectable); + + return computed(() => { + const podsByOwnerId = new Map(); + const statuses = { running: 0, failed: 0, pending: 0 }; + + for (const pod of podStore.contextItems) { + for (const ownerRef of pod.getOwnerRefs()) { + getOrInsert(podsByOwnerId, ownerRef.uid, []).push({ + status: pod.getStatus(), + }); + } + } + + for (const replicaSet of replicaSetStore.contextItems) { + const status = (podsByOwnerId.get(replicaSet.getId()) ?? []) + .map(pod => pod.status) + .reduce(foldPodStatusPhase, "running"); + + statuses[status]++; + } + + return statuses; + }); + }, +}); + +export default statusCountsForAllReplicaSetsInSelectedNamespacesInjectable; diff --git a/packages/core/src/renderer/components/+workloads-replicasets/total-count.injectable.ts b/packages/core/src/renderer/components/+workloads-replicasets/total-count.injectable.ts new file mode 100644 index 0000000000..aade82a6d2 --- /dev/null +++ b/packages/core/src/renderer/components/+workloads-replicasets/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 replicaSetStoreInjectable from "./store.injectable"; + +const totalCountOfReplicaSetsInSelectedNamespacesInjectable = getInjectable({ + id: "total-count-of-replica-sets-in-selected-namespaces", + instantiate: (di) => { + const store = di.inject(replicaSetStoreInjectable); + + return computed(() => store.getTotalCount()); + }, +}); + +export default totalCountOfReplicaSetsInSelectedNamespacesInjectable; diff --git a/packages/core/src/renderer/utils/fold-pod-status-phase.ts b/packages/core/src/renderer/utils/fold-pod-status-phase.ts new file mode 100644 index 0000000000..038dfc911e --- /dev/null +++ b/packages/core/src/renderer/utils/fold-pod-status-phase.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 { PodStatusPhase } from "../../common/k8s-api/endpoints"; + +export const foldPodStatusPhase = (previous: "failed" | "pending" | "running", current: PodStatusPhase): "failed" | "pending" | "running" => { + if (previous === "failed" || current === PodStatusPhase.FAILED) { + return "failed"; + } + + if (previous === "pending" || current === PodStatusPhase.PENDING) { + return "pending"; + } + + return "running"; +};