58 lines
2.0 KiB
JavaScript
58 lines
2.0 KiB
JavaScript
import { spawn } from "node:child_process";
|
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { setTimeout as delay } from "node:timers/promises";
|
|
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.
|
|
// - "delayed-ignoring": installs those handlers after a slow startup.
|
|
// - "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);
|
|
|
|
// Make the cancellation case exercise startup beyond its old 300 ms capture
|
|
// window deterministically, rather than relying on a busy CI runner.
|
|
if (mode === "delayed-ignoring") await delay(500);
|
|
|
|
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" || mode === "delayed-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);
|