refactor(cleanup): completar fase 5 con renombrados semánticos

This commit is contained in:
Pandipipas
2026-02-21 18:55:30 +01:00
parent 8047c99946
commit 710fea38c0
7 changed files with 114 additions and 113 deletions
+39 -38
View File
@@ -7,9 +7,9 @@ import { NODE_RUNTIME_NAME } from "../constants";
type NodecgProcessManagerConfig = {
isDev: boolean;
nodecgPath: string;
baseUrl: string;
runtimeConfig: AppRuntimeConfig;
nodecgRootPath: string;
nodecgBaseUrl: string;
appConfig: AppRuntimeConfig;
log: (...args: unknown[]) => void;
deps?: Partial<NodecgProcessManagerDeps>;
};
@@ -28,35 +28,35 @@ type NodecgProcessManagerDeps = {
};
export type NodecgProcessManager = {
startNodeCG: () => ChildProcess;
waitForNodeCGReady: (startTime: number) => Promise<void>;
stopNodeCG: () => Promise<void>;
startNodecgProcess: () => ChildProcess;
waitForNodecgReady: (startTime: number) => Promise<void>;
stopNodecgProcessGracefully: () => Promise<void>;
getProcess: () => ChildProcess | null;
};
export function createNodecgProcessManager({
isDev,
nodecgPath,
baseUrl,
runtimeConfig,
nodecgRootPath,
nodecgBaseUrl,
appConfig,
log,
deps,
}: NodecgProcessManagerConfig): NodecgProcessManager {
const resolvedDeps = resolveDeps(deps);
let nodecgProcess: ChildProcess | null = null;
let stopNodeCGPromise: Promise<void> | null = null;
let stopNodecgPromise: Promise<void> | null = null;
const startNodeCG = (): ChildProcess => {
validateNodeCGInstall(nodecgPath, runtimeConfig.bundleName, resolvedDeps.pathExists);
const startNodecgProcess = (): ChildProcess => {
validateNodecgInstall(nodecgRootPath, appConfig.bundleName, resolvedDeps.pathExists);
const indexPath = path.join(nodecgPath, "index.js");
const indexPath = path.join(nodecgRootPath, "index.js");
const child = resolvedDeps.spawnProcess(resolvedDeps.execPath, [indexPath], {
cwd: nodecgPath,
cwd: nodecgRootPath,
env: {
...resolvedDeps.env,
NODE_ENV: isDev ? "development" : "production",
NODECG_PORT: runtimeConfig.nodecgPort,
NODECG_PORT: appConfig.nodecgPort,
ELECTRON_RUN_AS_NODE: "1",
},
stdio: ["ignore", "pipe", "pipe"],
@@ -83,14 +83,14 @@ export function createNodecgProcessManager({
return child;
};
const waitForNodeCGReady = async (startTime: number): Promise<void> => {
while (Date.now() - startTime < runtimeConfig.startupTimeoutMs) {
const waitForNodecgReady = async (startTime: number): Promise<void> => {
while (Date.now() - startTime < appConfig.startupTimeoutMs) {
if (!nodecgProcess) {
throw new Error("NodeCG terminó antes de estar listo.");
}
try {
const response = await resolvedDeps.fetchUrl(baseUrl, { method: "GET" });
const response = await resolvedDeps.fetchUrl(nodecgBaseUrl, { method: "GET" });
if (response.ok || response.status === 404) {
return;
}
@@ -101,12 +101,12 @@ export function createNodecgProcessManager({
await sleep(500, resolvedDeps.setTimer);
}
throw new Error(`Timeout esperando NodeCG en ${baseUrl} (${runtimeConfig.startupTimeoutMs}ms).`);
throw new Error(`Timeout esperando NodeCG en ${nodecgBaseUrl} (${appConfig.startupTimeoutMs}ms).`);
};
const stopNodeCG = (): Promise<void> => {
if (stopNodeCGPromise) {
return stopNodeCGPromise;
const stopNodecgProcessGracefully = (): Promise<void> => {
if (stopNodecgPromise) {
return stopNodecgPromise;
}
if (!nodecgProcess || nodecgProcess.killed) {
@@ -122,14 +122,15 @@ export function createNodecgProcessManager({
}
log(`Stopping NodeCG pid=${pid}`);
killNodeCGProcessTree(pid, "SIGTERM", log, resolvedDeps);
killNodecgProcessTree(pid, "SIGTERM", log, resolvedDeps);
stopNodeCGPromise = new Promise((resolve) => {
stopNodecgPromise = new Promise((resolve) => {
const complete = () => {
if (nodecgProcess === processToStop) {
nodecgProcess = null;
}
stopNodeCGPromise = null;
stopNodecgPromise = null;
resolve();
};
@@ -140,18 +141,18 @@ export function createNodecgProcessManager({
resolvedDeps.setTimer(() => {
if (processToStop.exitCode === null && processToStop.signalCode === null) {
log(`NodeCG did not exit after SIGTERM, forcing SIGKILL pid=${pid}`);
killNodeCGProcessTree(pid, "SIGKILL", log, resolvedDeps);
killNodecgProcessTree(pid, "SIGKILL", log, resolvedDeps);
}
}, Math.max(0, runtimeConfig.nodecgKillTimeoutMs));
}, Math.max(0, appConfig.nodecgKillTimeoutMs));
});
return stopNodeCGPromise;
return stopNodecgPromise;
};
return {
startNodeCG,
waitForNodeCGReady,
stopNodeCG,
startNodecgProcess,
waitForNodecgReady,
stopNodecgProcessGracefully,
getProcess: () => nodecgProcess,
};
}
@@ -171,13 +172,13 @@ function resolveDeps(deps?: Partial<NodecgProcessManagerDeps>): NodecgProcessMan
};
}
function validateNodeCGInstall(nodecgPath: string, bundleName: string, pathExists: (candidatePath: string) => boolean): void {
const indexPath = path.join(nodecgPath, "index.js");
const nodecgBootstrapPath = path.join(nodecgPath, "node_modules", "nodecg", "dist", "server", "bootstrap.js");
const bundlePath = path.join(nodecgPath, "bundles", bundleName);
function validateNodecgInstall(nodecgRootPath: string, bundleName: string, pathExists: (candidatePath: string) => boolean): void {
const indexPath = path.join(nodecgRootPath, "index.js");
const nodecgBootstrapPath = path.join(nodecgRootPath, "node_modules", "nodecg", "dist", "server", "bootstrap.js");
const bundlePath = path.join(nodecgRootPath, "bundles", bundleName);
if (!pathExists(nodecgPath)) {
throw new Error(`No existe la carpeta NodeCG: ${nodecgPath}`);
if (!pathExists(nodecgRootPath)) {
throw new Error(`No existe la carpeta NodeCG: ${nodecgRootPath}`);
}
if (!pathExists(indexPath)) {
@@ -206,7 +207,7 @@ function validateNodeCGInstall(nodecgPath: string, bundleName: string, pathExist
}
}
function killNodeCGProcessTree(
function killNodecgProcessTree(
pid: number,
signal: NodeJS.Signals,
log: (...args: unknown[]) => void,