| 1 | import { spawn } from "node:child_process" |
| 2 | import { appendFileSync, writeFileSync } from "node:fs" |
| 3 | |
| 4 | // The leader and descendant share a process group and inherited stdio. The |
| 5 | // leader keeps the default SIGTERM behavior. The descendant either exits 200ms |
| 6 | // after SIGTERM or ignores it while writing heartbeats to the marker file. |
| 7 | const [role, mode, marker] = process.argv.slice(2) |
| 8 | |
| 9 | if (role === "leader") { |
| 10 | spawn(process.execPath, [process.argv[1], "descendant", mode, marker], { |
| 11 | stdio: ["ignore", "inherit", "inherit"] |
| 12 | }) |
| 13 | process.stdin.once("data", (data) => process.exit(data.toString().trim() === "exit 1" ? 1 : 0)) |
| 14 | setInterval(() => {}, 1_000) |
| 15 | } else { |
| 16 | if (mode === "exit-on-signal") { |
| 17 | process.on("SIGTERM", () => { |
| 18 | setTimeout(() => { |
| 19 | writeFileSync(marker, "exited") |
| 20 | process.exit(0) |
| 21 | }, 200) |
| 22 | }) |
| 23 | } else { |
| 24 | process.on("SIGTERM", () => {}) |
| 25 | appendFileSync(marker, "x") |
| 26 | setInterval(() => appendFileSync(marker, "x"), 10) |
| 27 | } |
| 28 | setTimeout(() => process.exit(1), 5_000) |
| 29 | process.stdout.write(`READY ${process.pid}\n`) |
| 30 | } |