Files
Miasma/src/utils/daemon.ts
T

46 lines
1.3 KiB
TypeScript

import { releaseLock } from "./lock";
import { logUtil } from "./logger";
/**
* Daemonize the current process: spawns a detached child and exits the parent.
*
* When __IS_DAEMON is already set this is a no-op (the child continues).
* Otherwise the parent releases its lock, spawns the child via Bun.spawn,
* unrefs it so the child outlives the parent, and exits once the child
* process is confirmed running (polls PID existence, 1s max).
*/
export function daemonize(): void {
if (process.env["__IS_DAEMON"]) return; // child — keep running
releaseLock();
const child = Bun.spawn({
cmd: [process.execPath, ...process.argv.slice(1)],
stdout: "ignore",
stderr: "ignore",
stdin: "ignore",
env: { ...process.env, __IS_DAEMON: "1" },
cwd: process.cwd(),
});
child.unref();
logUtil.log(`Backgrounded with PID ${child.pid}`);
// Poll until the child process actually exists, then exit the parent.
// Falls back to a hard exit after 1 second in case the child fails to start.
const start = Date.now();
const poll = setInterval(() => {
try {
process.kill(child.pid, 0); // signal 0 = existence check only
clearInterval(poll);
process.exit(0);
} catch {
if (Date.now() - start > 1000) {
clearInterval(poll);
process.exit(0);
}
}
}, 50);
}