From 72d82987f32dc2a0a5a2fe6d3763ec6fb353fec2 Mon Sep 17 00:00:00 2001 From: hensm Date: Tue, 20 Sep 2022 15:48:37 +0100 Subject: [PATCH] Fix bridge SIGTERM handling --- app/src/bridge/components/mediaServer.ts | 23 +++++++++++++---------- app/src/daemon.ts | 18 ++++++++++++++++-- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app/src/bridge/components/mediaServer.ts b/app/src/bridge/components/mediaServer.ts index 78ce44f..db6a573 100644 --- a/app/src/bridge/components/mediaServer.ts +++ b/app/src/bridge/components/mediaServer.ts @@ -179,16 +179,19 @@ export async function startMediaServer(filePath: string, port: number) { export function stopMediaServer() { return new Promise((resolve, reject) => { - if (mediaServer?.listening) { - mediaServer.close(err => { - if (err) { - reject(); - } else { - resolve(); - } - }); - - mediaServer = undefined; + if (!mediaServer?.listening) { + resolve(); + return; } + + mediaServer.close(err => { + if (err) { + reject(); + } else { + resolve(); + } + }); + + mediaServer = undefined; }); } diff --git a/app/src/daemon.ts b/app/src/daemon.ts index 09c79ee..f47e9cf 100644 --- a/app/src/daemon.ts +++ b/app/src/daemon.ts @@ -1,12 +1,22 @@ import http from "http"; import https from "https"; -import { spawn } from "child_process"; +import { ChildProcess, spawn } from "child_process"; import { Readable } from "stream"; import WebSocket from "ws"; import { DecodeTransform, EncodeTransform } from "./transforms.js"; +const bridgeInstances = new Set(); + +// Ensure child processes are killed on exit +process.on("SIGTERM", async () => { + for (const bridge of bridgeInstances) { + bridge.kill(); + } + process.exit(1); +}); + export interface DaemonOpts { host: string; port: number; @@ -46,6 +56,7 @@ export function init(opts: DaemonOpts) { * version of self in bridge mode. */ const bridge = spawn(process.execPath, [process.argv[1]]); + bridgeInstances.add(bridge); // socket -> bridge.stdin messageStream.pipe(new EncodeTransform()).pipe(bridge.stdin); @@ -61,7 +72,10 @@ export function init(opts: DaemonOpts) { // Handle termination socket.on("close", () => bridge.kill()); - bridge.on("exit", () => socket.close()); + bridge.on("exit", () => { + socket.close(); + bridgeInstances.delete(bridge); + }); }); /**