From 545a914c4c86bda3147b091a73f844f8d44d0c75 Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Sun, 6 Oct 2024 13:40:02 -0700 Subject: [PATCH] better shutdown logic to capture waveapp logs from wavesrv shutdown (#931) --- cmd/server/main-server.go | 1 + emain/emain.ts | 31 ++++++++++++++++++++++++++++--- frontend/app/store/ws.ts | 11 ++++++++++- frontend/app/store/wshrpcutil.ts | 5 +++++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/cmd/server/main-server.go b/cmd/server/main-server.go index 8b3e2dc83..6f149ff0c 100644 --- a/cmd/server/main-server.go +++ b/cmd/server/main-server.go @@ -65,6 +65,7 @@ func doShutdown(reason string) { watcher.Close() } time.Sleep(500 * time.Millisecond) + log.Printf("shutdown complete\n") os.Exit(0) }) } diff --git a/emain/emain.ts b/emain/emain.ts index d87c93100..ee6ed3fbe 100644 --- a/emain/emain.ts +++ b/emain/emain.ts @@ -15,7 +15,7 @@ import * as util from "util"; import winston from "winston"; import { initGlobal } from "../frontend/app/store/global"; import * as services from "../frontend/app/store/services"; -import { initElectronWshrpc } from "../frontend/app/store/wshrpcutil"; +import { initElectronWshrpc, shutdownWshrpc } from "../frontend/app/store/wshrpcutil"; import { WSServerEndpointVarName, WebServerEndpointVarName, getWebServerEndpoint } from "../frontend/util/endpoints"; import { fetch } from "../frontend/util/fetchutil"; import * as keyutil from "../frontend/util/keyutil"; @@ -41,6 +41,8 @@ import { configureAutoUpdater, updater } from "./updater"; const electronApp = electron.app; let WaveVersion = "unknown"; // set by WAVESRV-ESTART let WaveBuildTime = 0; // set by WAVESRV-ESTART +let forceQuit = false; +let isWaveSrvDead = false; const WaveAppPathVarName = "WAVETERM_APP_PATH"; const WaveSrvReadySignalPidVarName = "WAVETERM_READY_SIGNAL_PID"; @@ -167,10 +169,12 @@ function runWaveSrv(): Promise { env: envCopy, }); proc.on("exit", (e) => { - if (globalIsQuitting || updater?.status == "installing") { + if (updater?.status == "installing") { return; } console.log("wavesrv exited, shutting down"); + forceQuit = true; + isWaveSrvDead = true; electronApp.quit(); }); proc.on("spawn", (e) => { @@ -935,9 +939,30 @@ electronApp.on("window-all-closed", () => { electronApp.quit(); } }); -electronApp.on("before-quit", () => { +electronApp.on("before-quit", (e) => { globalIsQuitting = true; updater?.stop(); + waveSrvProc?.kill("SIGINT"); + shutdownWshrpc(); + if (forceQuit) { + return; + } + e.preventDefault(); + const allWindows = electron.BrowserWindow.getAllWindows(); + for (const window of allWindows) { + window.hide(); + } + if (isWaveSrvDead) { + console.log("wavesrv is dead, quitting immediately"); + forceQuit = true; + electronApp.quit(); + return; + } + setTimeout(() => { + console.log("waiting for wavesrv to exit..."); + forceQuit = true; + electronApp.quit(); + }, 3000); }); process.on("SIGINT", () => { console.log("Caught SIGINT, shutting down"); diff --git a/frontend/app/store/ws.ts b/frontend/app/store/ws.ts index 258d2f6bf..81a223662 100644 --- a/frontend/app/store/ws.ts +++ b/frontend/app/store/ws.ts @@ -44,6 +44,7 @@ class WSControl { baseHostPort: string; lastReconnectTime: number = 0; eoOpts: ElectronOverrideOpts; + noReconnect: boolean = false; constructor( baseHostPort: string, @@ -59,8 +60,13 @@ class WSControl { setInterval(this.sendPing.bind(this), 5000); } + shutdown() { + this.noReconnect = true; + this.wsConn.close(); + } + connectNow(desc: string) { - if (this.open) { + if (this.open || this.noReconnect) { return; } this.lastReconnectTime = Date.now(); @@ -82,6 +88,9 @@ class WSControl { } reconnect(forceClose?: boolean) { + if (this.noReconnect) { + return; + } if (this.open) { if (forceClose) { this.wsConn.close(); // this will force a reconnect diff --git a/frontend/app/store/wshrpcutil.ts b/frontend/app/store/wshrpcutil.ts index 69c4bac73..487fc2831 100644 --- a/frontend/app/store/wshrpcutil.ts +++ b/frontend/app/store/wshrpcutil.ts @@ -128,6 +128,10 @@ function initElectronWshrpc(electronClient: WshClient, eoOpts: ElectronOverrideO addWSReconnectHandler(wpsReconnectHandler); } +function shutdownWshrpc() { + globalWS?.shutdown(); +} + function initWshrpc(windowId: string): WSControl { DefaultRouter = new WshRouter(new UpstreamWshRpcProxy()); const handleFn = (event: WSEventType) => { @@ -163,5 +167,6 @@ export { sendRpcCommand, sendRpcResponse, sendWSCommand, + shutdownWshrpc, WindowRpcClient, };