mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Properly handle loading custom entity in cluster-frame
Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
parent
11386c0da5
commit
95a5307fcd
@ -300,11 +300,16 @@ export class ExtensionLoader {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected autoInitExtensions(register: (ext: LensExtension) => Promise<Disposer[]>) {
|
protected async loadExtensions(installedExtensions: Map<string, InstalledExtension>, register: (ext: LensExtension) => Promise<Disposer[]>) {
|
||||||
const loadingExtensions: ExtensionLoading[] = [];
|
// Steps of the function:
|
||||||
|
// 1. require and call .activate for each Extension
|
||||||
|
// 2. Wait until every extension's onActivate has been resolved
|
||||||
|
// 3. Call .enable for each extension
|
||||||
|
// 4. Return ExtensionLoading[]
|
||||||
|
|
||||||
reaction(() => this.toJSON(), async installedExtensions => {
|
const extensions = [...installedExtensions.entries()]
|
||||||
for (const [extId, extension] of installedExtensions) {
|
.map(([extId, extension]) => {
|
||||||
|
// for (const [extId, extension] of installedExtensions) {
|
||||||
const alreadyInit = this.instances.has(extId) || this.nonInstancesByName.has(extension.manifest.name);
|
const alreadyInit = this.instances.has(extId) || this.nonInstancesByName.has(extension.manifest.name);
|
||||||
|
|
||||||
if (extension.isCompatible && extension.isEnabled && !alreadyInit) {
|
if (extension.isCompatible && extension.isEnabled && !alreadyInit) {
|
||||||
@ -313,7 +318,8 @@ export class ExtensionLoader {
|
|||||||
|
|
||||||
if (!LensExtensionClass) {
|
if (!LensExtensionClass) {
|
||||||
this.nonInstancesByName.add(extension.manifest.name);
|
this.nonInstancesByName.add(extension.manifest.name);
|
||||||
continue;
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const instance = this.dependencies.createExtensionInstance(
|
const instance = this.dependencies.createExtensionInstance(
|
||||||
@ -321,27 +327,49 @@ export class ExtensionLoader {
|
|||||||
extension,
|
extension,
|
||||||
);
|
);
|
||||||
|
|
||||||
const loaded = instance.enable(register).catch((err) => {
|
return {
|
||||||
logger.error(`${logModule}: failed to enable`, { ext: extension, err });
|
extId,
|
||||||
});
|
instance,
|
||||||
|
|
||||||
loadingExtensions.push({
|
|
||||||
isBundled: extension.isBundled,
|
isBundled: extension.isBundled,
|
||||||
loaded,
|
activated: instance.activate()
|
||||||
});
|
};
|
||||||
this.instances.set(extId, instance);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`${logModule}: activation extension error`, { ext: extension, err });
|
logger.error(`${logModule}: activation extension error`, { ext: extension, err });
|
||||||
}
|
}
|
||||||
} else if (!extension.isEnabled && alreadyInit) {
|
} else if (!extension.isEnabled && alreadyInit) {
|
||||||
this.removeInstance(extId);
|
this.removeInstance(extId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, {
|
|
||||||
fireImmediately: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
return loadingExtensions;
|
return null;
|
||||||
|
})
|
||||||
|
// Remove null values
|
||||||
|
.filter(extension => Boolean(extension));
|
||||||
|
|
||||||
|
// We first need to wait until each extension's `onActivate` is resolved,
|
||||||
|
// as this might register new catalog categories. Afterwards we can safely .enable the extension.
|
||||||
|
await Promise.all(extensions.map(extension => extension.activated));
|
||||||
|
|
||||||
|
// Return ExtensionLoading[]
|
||||||
|
return extensions.map(extension => {
|
||||||
|
const loaded = extension.instance.enable(register).catch((err) => {
|
||||||
|
logger.error(`${logModule}: failed to enable`, { ext: extension, err });
|
||||||
|
});
|
||||||
|
|
||||||
|
this.instances.set(extension.extId, extension.instance);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isBundled: extension.isBundled,
|
||||||
|
loaded,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected autoInitExtensions(register: (ext: LensExtension) => Promise<Disposer[]>) {
|
||||||
|
// Setup reaction to load extensions on JSON changes
|
||||||
|
reaction(() => this.toJSON(), installedExtensions => this.loadExtensions(installedExtensions, register));
|
||||||
|
|
||||||
|
// Load initial extensions
|
||||||
|
return this.loadExtensions(this.toJSON(), register);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected requireExtension(extension: InstalledExtension): LensExtensionConstructor | null {
|
protected requireExtension(extension: InstalledExtension): LensExtensionConstructor | null {
|
||||||
|
|||||||
@ -86,7 +86,6 @@ export class LensExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.onActivate();
|
|
||||||
this._isEnabled = true;
|
this._isEnabled = true;
|
||||||
|
|
||||||
this[Disposers].push(...await register(this));
|
this[Disposers].push(...await register(this));
|
||||||
@ -113,6 +112,11 @@ export class LensExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
activate() {
|
||||||
|
return this.onActivate();
|
||||||
|
}
|
||||||
|
|
||||||
protected onActivate(): Promise<void> | void {
|
protected onActivate(): Promise<void> | void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,16 +12,19 @@ import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bu
|
|||||||
import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable";
|
import clusterFrameContextInjectable from "../../../cluster-frame-context/cluster-frame-context.injectable";
|
||||||
|
|
||||||
const initClusterFrameInjectable = getInjectable({
|
const initClusterFrameInjectable = getInjectable({
|
||||||
instantiate: (di) =>
|
instantiate: (di) => {
|
||||||
initClusterFrame({
|
const extensionLoader = di.inject(extensionLoaderInjectable);
|
||||||
|
|
||||||
|
return initClusterFrame({
|
||||||
hostedCluster: di.inject(hostedClusterInjectable),
|
hostedCluster: di.inject(hostedClusterInjectable),
|
||||||
loadExtensions: di.inject(extensionLoaderInjectable).loadOnClusterRenderer,
|
loadExtensions: extensionLoader.loadOnClusterRenderer.bind(extensionLoader),
|
||||||
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
|
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
|
||||||
frameRoutingId: di.inject(frameRoutingIdInjectable),
|
frameRoutingId: di.inject(frameRoutingIdInjectable),
|
||||||
emitEvent: di.inject(appEventBusInjectable).emit,
|
emitEvent: di.inject(appEventBusInjectable).emit,
|
||||||
|
|
||||||
clusterFrameContext: di.inject(clusterFrameContextInjectable),
|
clusterFrameContext: di.inject(clusterFrameContextInjectable),
|
||||||
}),
|
});
|
||||||
|
},
|
||||||
|
|
||||||
lifecycle: lifecycleEnum.singleton,
|
lifecycle: lifecycleEnum.singleton,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -11,15 +11,15 @@ import type { ExtensionLoading } from "../../../../extensions/extension-loader";
|
|||||||
import type { CatalogEntityRegistry } from "../../../api/catalog-entity-registry";
|
import type { CatalogEntityRegistry } from "../../../api/catalog-entity-registry";
|
||||||
|
|
||||||
interface Dependencies {
|
interface Dependencies {
|
||||||
loadExtensions: () => ExtensionLoading[]
|
loadExtensions: () => Promise<ExtensionLoading[]>;
|
||||||
|
|
||||||
// TODO: Move usages of third party library behind abstraction
|
// TODO: Move usages of third party library behind abstraction
|
||||||
ipcRenderer: { send: (name: string) => void }
|
ipcRenderer: { send: (name: string) => void };
|
||||||
|
|
||||||
// TODO: Remove dependencies being here only for correct timing of initialization
|
// TODO: Remove dependencies being here only for correct timing of initialization
|
||||||
bindProtocolAddRouteHandlers: () => void;
|
bindProtocolAddRouteHandlers: () => void;
|
||||||
lensProtocolRouterRenderer: { init: () => void };
|
lensProtocolRouterRenderer: { init: () => void };
|
||||||
catalogEntityRegistry: CatalogEntityRegistry
|
catalogEntityRegistry: CatalogEntityRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
const logPrefix = "[ROOT-FRAME]:";
|
const logPrefix = "[ROOT-FRAME]:";
|
||||||
@ -40,7 +40,7 @@ export const initRootFrame =
|
|||||||
// maximum time to let bundled extensions finish loading
|
// maximum time to let bundled extensions finish loading
|
||||||
const timeout = delay(10000);
|
const timeout = delay(10000);
|
||||||
|
|
||||||
const loadingExtensions = loadExtensions();
|
const loadingExtensions = await loadExtensions();
|
||||||
|
|
||||||
const loadingBundledExtensions = loadingExtensions
|
const loadingBundledExtensions = loadingExtensions
|
||||||
.filter((e) => e.isBundled)
|
.filter((e) => e.isBundled)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user