mirror of
https://github.com/Pandipipas/scoreko-electron-dev.git
synced 2026-06-06 05:32:06 +00:00
feat: Implement application bootstrap and window management
- Added bootstrap functionality to initialize the Electron application. - Created a new paths module to manage application paths and URLs. - Introduced a shutdown service to handle graceful application shutdowns. - Refactored error logging to use a dedicated logger module. - Implemented process killing logic for NodeCG processes across platforms. - Established navigation policies for internal and external URL handling in windows. - Developed window service for creating and managing application windows. - Added tests for application paths, application controller, navigation policies, process killer, and shutdown service.
This commit is contained in:
@@ -5,6 +5,7 @@ import path from "node:path";
|
||||
|
||||
import { AppRuntimeConfig } from "../config/runtime-config";
|
||||
import { NODE_RUNTIME_NAME } from "../constants";
|
||||
import { killProcessTree } from "./platform-process-killer";
|
||||
|
||||
type NodecgProcessManagerConfig = {
|
||||
isDev: boolean;
|
||||
@@ -161,7 +162,12 @@ export function createNodecgProcessManager({
|
||||
}
|
||||
|
||||
log(`Stopping NodeCG pid=${pid}`);
|
||||
killNodecgProcessTree(pid, "SIGTERM", log, resolvedDeps);
|
||||
killProcessTree(pid, "SIGTERM", {
|
||||
platform: resolvedDeps.platform,
|
||||
spawnProcess: resolvedDeps.spawnProcess,
|
||||
killProcess: resolvedDeps.killProcess,
|
||||
log,
|
||||
});
|
||||
|
||||
stopNodecgPromise = new Promise((resolve) => {
|
||||
let completed = false;
|
||||
@@ -189,7 +195,12 @@ export function createNodecgProcessManager({
|
||||
() => {
|
||||
if (processToStop.exitCode === null && processToStop.signalCode === null) {
|
||||
log(`NodeCG did not exit after SIGTERM, forcing SIGKILL pid=${pid}`);
|
||||
killNodecgProcessTree(pid, "SIGKILL", log, resolvedDeps);
|
||||
killProcessTree(pid, "SIGKILL", {
|
||||
platform: resolvedDeps.platform,
|
||||
spawnProcess: resolvedDeps.spawnProcess,
|
||||
killProcess: resolvedDeps.killProcess,
|
||||
log,
|
||||
});
|
||||
complete();
|
||||
}
|
||||
},
|
||||
@@ -315,39 +326,6 @@ function probePortAvailable(port: number): Promise<boolean> {
|
||||
});
|
||||
}
|
||||
|
||||
function killNodecgProcessTree(
|
||||
pid: number,
|
||||
signal: NodeJS.Signals,
|
||||
log: (...args: unknown[]) => void,
|
||||
deps: Pick<NodecgProcessManagerDeps, "platform" | "spawnProcess" | "killProcess">,
|
||||
): boolean {
|
||||
if (deps.platform === "win32") {
|
||||
const force = signal === "SIGKILL" ? "/F" : "";
|
||||
const killer = deps.spawnProcess("taskkill", ["/pid", String(pid), "/T", ...(force ? [force] : [])], {
|
||||
stdio: "ignore",
|
||||
shell: true,
|
||||
});
|
||||
|
||||
killer.on("error", (error) => {
|
||||
log(`taskkill error for pid=${pid}`, error);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
deps.killProcess(-pid, signal);
|
||||
return true;
|
||||
} catch {
|
||||
try {
|
||||
deps.killProcess(pid, signal);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms: number, setTimer: (handler: () => void, timeoutMs: number) => unknown): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
setTimer(resolve, ms);
|
||||
|
||||
Reference in New Issue
Block a user