52 lines
1.6 KiB
JavaScript
52 lines
1.6 KiB
JavaScript
import { spawn } from "node:child_process";
|
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
// Writes a periodic report, then behaves by mode:
|
|
// - "cooperative": stays alive; SIGTERM prints a line, writes a final report
|
|
// and exits cleanly.
|
|
// - "ignoring": stays alive and swallows SIGTERM and SIGINT, so only SIGKILL
|
|
// ends the process.
|
|
// - "exits": exits on its own at once.
|
|
// - "descendant": cooperates while leaving a SIGTERM-ignoring child for owned cleanup.
|
|
// An optional third argument is the exit code a cooperative finalizer uses.
|
|
const [mode, directory, finalExitCode = "0"] = process.argv.slice(2);
|
|
|
|
writeFileSync(join(directory, "pid.txt"), String(process.pid));
|
|
writeFileSync(
|
|
join(directory, "periodic.json"),
|
|
JSON.stringify({ phase: "periodic" }),
|
|
);
|
|
|
|
if (mode === "exits") process.exit(0);
|
|
|
|
if (mode === "descendant") {
|
|
const childDirectory = join(directory, "descendant");
|
|
mkdirSync(childDirectory);
|
|
spawn(
|
|
process.execPath,
|
|
[fileURLToPath(import.meta.url), "ignoring", childDirectory],
|
|
{ detached: true, stdio: "ignore" },
|
|
);
|
|
}
|
|
|
|
if (mode === "ignoring") {
|
|
process.on("SIGTERM", () => {
|
|
writeFileSync(join(directory, "sigterm-received"), "received");
|
|
});
|
|
process.on("SIGINT", () => undefined);
|
|
} else {
|
|
process.on("SIGTERM", () => {
|
|
writeFileSync(join(directory, "sigterm-received"), "received");
|
|
process.stdout.write("finalized\n");
|
|
writeFileSync(
|
|
join(directory, "final.json"),
|
|
JSON.stringify({ phase: "final" }),
|
|
);
|
|
process.exit(Number(finalExitCode));
|
|
});
|
|
}
|
|
|
|
setInterval(() => undefined, 1_000);
|