diff --git a/src/main/services/bs-launcher/abstract-launcher.service.ts b/src/main/services/bs-launcher/abstract-launcher.service.ts index b5827999d..7dfb49466 100644 --- a/src/main/services/bs-launcher/abstract-launcher.service.ts +++ b/src/main/services/bs-launcher/abstract-launcher.service.ts @@ -3,6 +3,7 @@ import { BSLocalVersionService } from "../bs-local-version.service"; import { ChildProcessWithoutNullStreams, SpawnOptionsWithoutStdio, spawn } from "child_process"; import path from "path"; import log from "electron-log"; +import { sToMs } from "shared/helpers/time.helpers"; export abstract class AbstractLauncherService { @@ -46,20 +47,40 @@ export abstract class AbstractLauncherService { } - protected launchBs(bsExePath: string, args: string[], options?: SpawnOptionsWithoutStdio): {process: ChildProcessWithoutNullStreams, exit: Promise} { + protected launchBs(bsExePath: string, args: string[], options?: SpawnBsProcessOptions): {process: ChildProcessWithoutNullStreams, exit: Promise} { const process = this.launchBSProcess(bsExePath, args, options); + let timoutId: NodeJS.Timeout; + const exit = new Promise((resolve, reject) => { + process.on("error", (err) => { log.error(`Error while launching BS`, err); reject(err); }); + process.on("exit", (code) => { log.info(`BS process exit with code ${code}`); resolve(code); }); + + const unrefAfter = options?.unrefAfter ?? sToMs(10); + + timoutId = setTimeout(() => { + log.error("BS process unref after timeout", unrefAfter); + process.unref(); + process.removeAllListeners(); + resolve(-1); + }, unrefAfter); + + }).finally(() => { + clearTimeout(timoutId); }); return { process, exit }; } } + +export type SpawnBsProcessOptions = { + unrefAfter?: number; +} & SpawnOptionsWithoutStdio;