From 8e9a0cc4b7e42bbd6957d8ab3d0c72389a37aae0 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Tue, 2 Feb 2021 16:28:52 -0500 Subject: [PATCH] add waiting for renderer and extensions to load before broadcasting handlers Signed-off-by: Sebastian Malton --- src/common/ipc.ts | 2 +- src/extensions/extension-loader.ts | 10 ++++++++++ src/main/index.ts | 12 +++++++++++- src/main/protocol-handler/router.ts | 15 ++++++++++++--- src/main/window-manager.ts | 6 +++++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/common/ipc.ts b/src/common/ipc.ts index c2f8562cf7..3b1cd6333d 100644 --- a/src/common/ipc.ts +++ b/src/common/ipc.ts @@ -47,7 +47,7 @@ export async function broadcastMessage(channel: string, ...args: any[]) { view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); } } catch (error) { - logger.error("[IPC]: failed to send IPC message", { error }); + logger.error("[IPC]: failed to send IPC message", { error: String(error) }); } } } diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index 5a3715969f..b4aedaf274 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -66,6 +66,16 @@ export class ExtensionLoader { return extensions; } + getExtensionByName(name: string): LensExtension | null { + for (const [, val] of this.instances) { + if (val.name === name) { + return val; + } + } + + return null; + } + // Transform userExtensions to a state object for storing into ExtensionsStore @computed get storeState() { return Object.fromEntries( diff --git a/src/main/index.ts b/src/main/index.ts index 7008a1128d..f6bc0bfcd8 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -73,7 +73,7 @@ app.on("second-instance", (event, argv) => { .catch(error => logger.error(`${LensProtocolRouterMain.LoggingPrefix}: an error occured`, { error, rawUrl: arg })); } } - + windowManager?.ensureMainWindow(); }); @@ -127,6 +127,16 @@ app.on("ready", async () => { extensionLoader.init(); extensionDiscovery.init(); windowManager = WindowManager.getInstance(proxyPort); + windowManager.whenLoaded.then(() => { + LensProtocolRouterMain + .getInstance() + .rendererLoaded = true; + }); + extensionLoader.whenLoaded.then(() => { + LensProtocolRouterMain + .getInstance() + .extensionsLoaded = true; + }); // call after windowManager to see splash earlier try { diff --git a/src/main/protocol-handler/router.ts b/src/main/protocol-handler/router.ts index 65752e716b..20962372b2 100644 --- a/src/main/protocol-handler/router.ts +++ b/src/main/protocol-handler/router.ts @@ -3,6 +3,7 @@ import * as proto from "../../common/protocol-handler"; import Url from "url-parse"; import { LensExtension } from "../../extensions/lens-extension"; import { broadcastMessage } from "../../common/ipc"; +import { observable, when } from "mobx"; export interface FallbackHandler { (name: string): Promise; @@ -11,6 +12,9 @@ export interface FallbackHandler { export class LensProtocolRouterMain extends proto.LensProtocolRouter { private missingExtensionHandlers: FallbackHandler[] = []; + @observable rendererLoaded = false; + @observable extensionsLoaded = false; + /** * Find the most specific registered handler, if it exists, and invoke it. * @@ -31,6 +35,8 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter { case "app": return this._routeToInternal(url); case "extension": + await when(() => this.extensionsLoaded); + return this._routeToExtension(url); default: throw new proto.RoutingError(proto.RoutingErrorType.INVALID_HOST, url); @@ -69,12 +75,14 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter { return ""; } - protected _routeToInternal(url: Url): void { + protected async _routeToInternal(url: Url): Promise { const rawUrl = url.toString(); // for sending to renderer super._routeToInternal(url); - broadcastMessage(proto.ProtocolHandlerInternal, rawUrl); + await when(() => this.rendererLoaded); + + return broadcastMessage(proto.ProtocolHandlerInternal, rawUrl); } protected async _routeToExtension(url: Url): Promise { @@ -88,8 +96,9 @@ export class LensProtocolRouterMain extends proto.LensProtocolRouter { * argument. */ await super._routeToExtension(new Url(url.toString(), true)); + await when(() => this.rendererLoaded); - broadcastMessage(proto.ProtocolHandlerExtension, rawUrl); + return broadcastMessage(proto.ProtocolHandlerExtension, rawUrl); } /** diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index bf7458afa0..f481c6450f 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -1,5 +1,5 @@ import type { ClusterId } from "../common/cluster-store"; -import { observable } from "mobx"; +import { observable, when } from "mobx"; import { app, BrowserWindow, dialog, shell, webContents } from "electron"; import windowStateKeeper from "electron-window-state"; import { appEventBus } from "../common/event-bus"; @@ -15,6 +15,9 @@ export class WindowManager extends Singleton { protected windowState: windowStateKeeper.State; protected disposers: Record = {}; + @observable mainViewInitiallyLoaded = false; + whenLoaded = when(() => this.mainViewInitiallyLoaded); + @observable activeClusterId: ClusterId; constructor(protected proxyPort: number) { @@ -91,6 +94,7 @@ export class WindowManager extends Singleton { setTimeout(() => { appEventBus.emit({ name: "app", action: "start" }); }, 1000); + this.mainViewInitiallyLoaded = true; } catch (err) { dialog.showErrorBox("ERROR!", err.toString()); }