Refactor start and dev commands. Start in child processes. Handle errors better
This commit is contained in:
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
import { spawn } from "bun";
|
||||
// Only the "supervisor" respawns. The child sets this env var so it won't respawn itself.
|
||||
const IS_CHILD = process.env.__RESPAWN_CHILD === "1";
|
||||
let shuttingDown = false;
|
||||
async function cleanup() {
|
||||
// Put real cleanup here: close DB handles, servers, file descriptors, timers, etc.
|
||||
// Must be awaitable — do NOT rely on process.on("exit") for this.
|
||||
}
|
||||
function respawn(code) {
|
||||
const child = spawn({
|
||||
cmd: [process.execPath, ...process.argv.slice(1)],
|
||||
stdio: ["inherit", "inherit", "inherit"],
|
||||
env: { ...process.env, __RESPAWN_CHILD: "1" },
|
||||
// Detach so the child survives independently and gets its own process group.
|
||||
// Without this, killing the parent's group can take the child with it.
|
||||
});
|
||||
// Let the child live on its own.
|
||||
child.unref?.();
|
||||
}
|
||||
async function shutdown(code) {
|
||||
if (shuttingDown)
|
||||
return;
|
||||
shuttingDown = true;
|
||||
try {
|
||||
await cleanup();
|
||||
}
|
||||
catch (e) {
|
||||
console.error("cleanup failed:", e);
|
||||
}
|
||||
// Only the supervisor respawns, and only on abnormal exit.
|
||||
if (!IS_CHILD && code !== 0) {
|
||||
respawn(code);
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
// Catch the things that actually fire *before* exit, where async works.
|
||||
process.on("SIGINT", () => shutdown(130));
|
||||
process.on("SIGTERM", () => shutdown(143));
|
||||
process.on("uncaughtException", (err) => {
|
||||
console.error(err);
|
||||
shutdown(1);
|
||||
});
|
||||
process.on("unhandledRejection", (err) => {
|
||||
console.error(err);
|
||||
shutdown(1);
|
||||
});
|
||||
Reference in New Issue
Block a user