From 497f63fde630098d6322842f835b52cc5d61f766 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 15 Mar 2023 08:26:28 -0400 Subject: [PATCH] Move activating cluster into injectable IPC (#7355) Signed-off-by: Sebastian Malton --- .../catalog-entities/kubernetes-cluster.ts | 22 +++++--------- packages/core/src/common/ipc/cluster.ts | 1 - .../request-from-channel-injection-token.ts | 4 +++ .../cluster/activation/common/channels.ts | 18 +++++++++++ .../activation/common/request-token.ts | 14 +++++++++ .../main/activate-listener.injectable.ts | 14 +++++++++ .../main/request-activation.injectable.ts | 30 +++++++++++++++++++ .../renderer/request-activation.injectable.ts | 20 +++++++++++++ .../setup-ipc-main-handlers.ts | 14 +-------- .../cluster-manager/cluster-status.tsx | 10 +++++-- .../cluster-manager/cluster-view.tsx | 7 +++-- packages/core/src/renderer/ipc/index.ts | 6 +--- 12 files changed, 122 insertions(+), 38 deletions(-) create mode 100644 packages/core/src/features/cluster/activation/common/channels.ts create mode 100644 packages/core/src/features/cluster/activation/common/request-token.ts create mode 100644 packages/core/src/features/cluster/activation/main/activate-listener.injectable.ts create mode 100644 packages/core/src/features/cluster/activation/main/request-activation.injectable.ts create mode 100644 packages/core/src/features/cluster/activation/renderer/request-activation.injectable.ts diff --git a/packages/core/src/common/catalog-entities/kubernetes-cluster.ts b/packages/core/src/common/catalog-entities/kubernetes-cluster.ts index 7615c19f3e..aa3dd68af2 100644 --- a/packages/core/src/common/catalog-entities/kubernetes-cluster.ts +++ b/packages/core/src/common/catalog-entities/kubernetes-cluster.ts @@ -9,11 +9,12 @@ import { broadcastMessage } from "../ipc"; import { app } from "electron"; import type { CatalogEntityConstructor, CatalogEntitySpec } from "../catalog/catalog-entity"; import { IpcRendererNavigationEvents } from "../ipc/navigation-events"; -import { requestClusterActivation, requestClusterDisconnection } from "../../renderer/ipc"; +import { requestClusterDisconnection } from "../../renderer/ipc"; import KubeClusterCategoryIcon from "./icons/kubernetes.svg"; import getClusterByIdInjectable from "../cluster-store/get-by-id.injectable"; import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import clusterConnectionInjectable from "../../main/cluster/cluster-connection.injectable"; +import { requestClusterActivationInjectionToken } from "../../features/cluster/activation/common/request-token"; export interface KubernetesClusterPrometheusMetrics { address?: { @@ -77,21 +78,12 @@ export class KubernetesCluster< public readonly kind = KubernetesCluster.kind; async connect(): Promise { - if (app) { - const di = getLegacyGlobalDiForExtensionApi(); - const getClusterById = di.inject(getClusterByIdInjectable); - const cluster = getClusterById(this.getId()); + const di = getLegacyGlobalDiForExtensionApi(); + const requestClusterActivation = di.inject(requestClusterActivationInjectionToken); - if (!cluster) { - return; - } - - const connectionCluster = di.inject(clusterConnectionInjectable, cluster); - - await connectionCluster.activate(); - } else { - await requestClusterActivation(this.getId(), false); - } + await requestClusterActivation({ + clusterId: this.getId(), + }); } async disconnect(): Promise { diff --git a/packages/core/src/common/ipc/cluster.ts b/packages/core/src/common/ipc/cluster.ts index 53061abf60..3b22e4ee57 100644 --- a/packages/core/src/common/ipc/cluster.ts +++ b/packages/core/src/common/ipc/cluster.ts @@ -3,7 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -export const clusterActivateHandler = "cluster:activate"; export const clusterSetFrameIdHandler = "cluster:set-frame-id"; export const clusterVisibilityHandler = "cluster:visibility"; export const clusterDisconnectHandler = "cluster:disconnect"; diff --git a/packages/core/src/common/utils/channel/request-from-channel-injection-token.ts b/packages/core/src/common/utils/channel/request-from-channel-injection-token.ts index dc3d1fa1a4..939cc23f9d 100644 --- a/packages/core/src/common/utils/channel/request-from-channel-injection-token.ts +++ b/packages/core/src/common/utils/channel/request-from-channel-injection-token.ts @@ -10,6 +10,10 @@ export interface RequestFromChannel { (channel: RequestChannel): Promise>; } +export type ChannelRequester = Channel extends RequestChannel + ? (req: Request) => Promise> + : never; + export const requestFromChannelInjectionToken = getInjectionToken({ id: "request-from-request-channel", }); diff --git a/packages/core/src/features/cluster/activation/common/channels.ts b/packages/core/src/features/cluster/activation/common/channels.ts new file mode 100644 index 0000000000..8ab63e7645 --- /dev/null +++ b/packages/core/src/features/cluster/activation/common/channels.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 type { ClusterId } from "../../../../common/cluster-types"; +import { getRequestChannel } from "../../../../common/utils/channel/get-request-channel"; + +export interface ActivateCluster { + clusterId: ClusterId; + + /** + * @default false + */ + force?: boolean; +} + +export const activateClusterChannel = getRequestChannel("activate-cluster"); diff --git a/packages/core/src/features/cluster/activation/common/request-token.ts b/packages/core/src/features/cluster/activation/common/request-token.ts new file mode 100644 index 0000000000..0838c3f1ba --- /dev/null +++ b/packages/core/src/features/cluster/activation/common/request-token.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { ChannelRequester } from "../../../../common/utils/channel/request-from-channel-injection-token"; +import type { activateClusterChannel } from "./channels"; + +export type RequestClusterActivation = ChannelRequester; + +export const requestClusterActivationInjectionToken = getInjectionToken({ + id: "request-cluster-activation-token", +}); diff --git a/packages/core/src/features/cluster/activation/main/activate-listener.injectable.ts b/packages/core/src/features/cluster/activation/main/activate-listener.injectable.ts new file mode 100644 index 0000000000..4ce22e6311 --- /dev/null +++ b/packages/core/src/features/cluster/activation/main/activate-listener.injectable.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens"; +import { activateClusterChannel } from "../common/channels"; +import requestClusterActivationInjectable from "./request-activation.injectable"; + +const activateClusterRequestChannelListenerInjectable = getRequestChannelListenerInjectable({ + channel: activateClusterChannel, + handler: (di) => di.inject(requestClusterActivationInjectable), +}); + +export default activateClusterRequestChannelListenerInjectable; diff --git a/packages/core/src/features/cluster/activation/main/request-activation.injectable.ts b/packages/core/src/features/cluster/activation/main/request-activation.injectable.ts new file mode 100644 index 0000000000..c498040fc0 --- /dev/null +++ b/packages/core/src/features/cluster/activation/main/request-activation.injectable.ts @@ -0,0 +1,30 @@ +/** + * 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 getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable"; +import clusterConnectionInjectable from "../../../../main/cluster/cluster-connection.injectable"; +import { requestClusterActivationInjectionToken } from "../common/request-token"; + +const requestClusterActivationInjectable = getInjectable({ + id: "request-cluster-activation", + instantiate: (di) => { + const getClusterById = di.inject(getClusterByIdInjectable); + + return async ({ clusterId, force = false }) => { + const cluster = getClusterById(clusterId); + + if (!cluster) { + return; + } + + const connection = di.inject(clusterConnectionInjectable, cluster); + + await connection.activate(force); + }; + }, + injectionToken: requestClusterActivationInjectionToken, +}); + +export default requestClusterActivationInjectable; diff --git a/packages/core/src/features/cluster/activation/renderer/request-activation.injectable.ts b/packages/core/src/features/cluster/activation/renderer/request-activation.injectable.ts new file mode 100644 index 0000000000..1677d67792 --- /dev/null +++ b/packages/core/src/features/cluster/activation/renderer/request-activation.injectable.ts @@ -0,0 +1,20 @@ +/** + * 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 requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable"; +import { activateClusterChannel } from "../common/channels"; +import { requestClusterActivationInjectionToken } from "../common/request-token"; + +const requestClusterActivationInjectable = getInjectable({ + id: "request-cluster-activation", + instantiate: (di) => { + const requestFromChannel = di.inject(requestFromChannelInjectable); + + return (req) => requestFromChannel(activateClusterChannel, req); + }, + injectionToken: requestClusterActivationInjectionToken, +}); + +export default requestClusterActivationInjectable; diff --git a/packages/core/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts b/packages/core/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts index ddfc3f2003..987903fc3f 100644 --- a/packages/core/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts +++ b/packages/core/src/main/electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.ts @@ -5,7 +5,7 @@ import type { IpcMainInvokeEvent } from "electron"; import { BrowserWindow, Menu } from "electron"; import { clusterFrameMap } from "../../../../common/cluster-frames"; -import { clusterActivateHandler, clusterSetFrameIdHandler, clusterDisconnectHandler, clusterStates } from "../../../../common/ipc/cluster"; +import { clusterSetFrameIdHandler, clusterDisconnectHandler, clusterStates } from "../../../../common/ipc/cluster"; import type { ClusterId } from "../../../../common/cluster-types"; import type { ClusterStore } from "../../../../common/cluster-store/cluster-store"; import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../common/ipc"; @@ -37,18 +37,6 @@ export const setupIpcMainHandlers = ({ pushCatalogToRenderer, getClusterConnection, }: Dependencies) => { - ipcMainHandle(clusterActivateHandler, async (event, clusterId: ClusterId, force = false) => { - const cluster = getClusterById(clusterId); - - if (!cluster) { - return; - } - - const clusterConnection = getClusterConnection(cluster); - - await clusterConnection.activate(force); - }); - ipcMainHandle(clusterSetFrameIdHandler, (event: IpcMainInvokeEvent, clusterId: ClusterId) => { const cluster = getClusterById(clusterId); diff --git a/packages/core/src/renderer/components/cluster-manager/cluster-status.tsx b/packages/core/src/renderer/components/cluster-manager/cluster-status.tsx index 36e5f2e37c..1704d2c604 100644 --- a/packages/core/src/renderer/components/cluster-manager/cluster-status.tsx +++ b/packages/core/src/renderer/components/cluster-manager/cluster-status.tsx @@ -17,11 +17,12 @@ import { Icon } from "../icon"; import { Spinner } from "../spinner"; import type { KubeAuthUpdate } from "../../../common/cluster-types"; import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry"; -import { requestClusterActivation } from "../../ipc"; import type { NavigateToEntitySettings } from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable"; import { withInjectables } from "@ogre-tools/injectable-react"; import navigateToEntitySettingsInjectable from "../../../common/front-end-routing/routes/entity-settings/navigate-to-entity-settings.injectable"; import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; +import type { RequestClusterActivation } from "../../../features/cluster/activation/common/request-token"; +import requestClusterActivationInjectable from "../../../features/cluster/activation/renderer/request-activation.injectable"; export interface ClusterStatusProps { className?: IClassName; @@ -31,6 +32,7 @@ export interface ClusterStatusProps { interface Dependencies { navigateToEntitySettings: NavigateToEntitySettings; entityRegistry: CatalogEntityRegistry; + requestClusterActivation: RequestClusterActivation; } @observer @@ -83,7 +85,10 @@ class NonInjectedClusterStatus extends React.Component(N ...props, navigateToEntitySettings: di.inject(navigateToEntitySettingsInjectable), entityRegistry: di.inject(catalogEntityRegistryInjectable), + requestClusterActivation: di.inject(requestClusterActivationInjectable), }), }); diff --git a/packages/core/src/renderer/components/cluster-manager/cluster-view.tsx b/packages/core/src/renderer/components/cluster-manager/cluster-view.tsx index 60170e1741..6749fdd9d3 100644 --- a/packages/core/src/renderer/components/cluster-manager/cluster-view.tsx +++ b/packages/core/src/renderer/components/cluster-manager/cluster-view.tsx @@ -11,7 +11,6 @@ import { disposeOnUnmount, observer } from "mobx-react"; import { ClusterStatus } from "./cluster-status"; import type { ClusterFrameHandler } from "./cluster-frame-handler"; import type { Cluster } from "../../../common/cluster/cluster"; -import { requestClusterActivation } from "../../ipc"; import { withInjectables } from "@ogre-tools/injectable-react"; import type { NavigateToCatalog } from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable"; import navigateToCatalogInjectable from "../../../common/front-end-routing/routes/catalog/navigate-to-catalog.injectable"; @@ -21,6 +20,8 @@ import type { CatalogEntityRegistry } from "../../api/catalog/entity/registry"; import catalogEntityRegistryInjectable from "../../api/catalog/entity/registry.injectable"; import type { GetClusterById } from "../../../common/cluster-store/get-by-id.injectable"; import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable"; +import type { RequestClusterActivation } from "../../../features/cluster/activation/common/request-token"; +import requestClusterActivationInjectable from "../../../features/cluster/activation/renderer/request-activation.injectable"; interface Dependencies { clusterId: IComputedValue; @@ -28,6 +29,7 @@ interface Dependencies { navigateToCatalog: NavigateToCatalog; entityRegistry: CatalogEntityRegistry; getClusterById: GetClusterById; + requestClusterActivation: RequestClusterActivation; } @observer @@ -83,7 +85,7 @@ class NonInjectedClusterView extends React.Component { this.props.clusterFrames.setVisibleCluster(clusterId); this.props.clusterFrames.initView(clusterId); - requestClusterActivation(clusterId, false); // activate and fetch cluster's state from main + this.props.requestClusterActivation({ clusterId }); this.props.entityRegistry.activeEntity = clusterId; }, { fireImmediately: true, @@ -117,6 +119,7 @@ export const ClusterView = withInjectables(NonInjectedClusterView, clusterFrames: di.inject(clusterFrameHandlerInjectable), entityRegistry: di.inject(catalogEntityRegistryInjectable), getClusterById: di.inject(getClusterByIdInjectable), + requestClusterActivation: di.inject(requestClusterActivationInjectable), }), }); diff --git a/packages/core/src/renderer/ipc/index.ts b/packages/core/src/renderer/ipc/index.ts index f8ebfc2de0..c4d126a648 100644 --- a/packages/core/src/renderer/ipc/index.ts +++ b/packages/core/src/renderer/ipc/index.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { clusterActivateHandler, clusterDisconnectHandler, clusterSetFrameIdHandler, clusterStates } from "../../common/ipc/cluster"; +import { clusterDisconnectHandler, clusterSetFrameIdHandler, clusterStates } from "../../common/ipc/cluster"; import type { ClusterId, ClusterState } from "../../common/cluster-types"; import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel, type WindowAction } from "../../common/ipc/window"; import { extensionDiscoveryStateChannel, extensionLoaderFromMainChannel } from "../../common/ipc/extension-handling"; @@ -46,10 +46,6 @@ export function requestSetClusterFrameId(clusterId: ClusterId): Promise { return requestMain(clusterSetFrameIdHandler, clusterId); } -export function requestClusterActivation(clusterId: ClusterId, force?: boolean): Promise { - return requestMain(clusterActivateHandler, clusterId, force); -} - export function requestClusterDisconnection(clusterId: ClusterId, force?: boolean): Promise { return requestMain(clusterDisconnectHandler, clusterId, force); }