feat(FN-5189): complete Step 3 — migrate supervised spawns
Fusion-Task-Id: FN-5189 Fusion-Task-Lineage: 4caa3f0a-af81-4c60-88e8-de229ed72e08
This commit is contained in:
committed by
gsxdsm
parent
87ea63c7c3
commit
818db4a714
@@ -14,6 +14,8 @@ type ShutdownReason =
|
||||
| { kind: "test"; label: string };
|
||||
|
||||
export interface SuperviseSpawnOptions extends Omit<SpawnOptions, "detached"> {
|
||||
/** Override spawn for tests or alternate process factories. */
|
||||
spawnImpl?: typeof spawn;
|
||||
/**
|
||||
* Grace period between SIGTERM and SIGKILL when the supervisor tears a child
|
||||
* down because the parent is exiting or a lifetime limit expires.
|
||||
@@ -246,11 +248,12 @@ export function superviseSpawn(
|
||||
const {
|
||||
killGraceMs = DEFAULT_KILL_GRACE_MS,
|
||||
maxLifetimeMs = DEFAULT_MAX_LIFETIME_MS,
|
||||
spawnImpl = spawn,
|
||||
...spawnOptions
|
||||
} = options;
|
||||
|
||||
const processGroup = usesProcessGroup();
|
||||
const child = spawn(command, [...args], {
|
||||
const child = spawnImpl(command, [...args], {
|
||||
...spawnOptions,
|
||||
detached: processGroup,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { spawn } from "node:child_process";
|
||||
import { superviseSpawn } from "./process-supervisor.js";
|
||||
|
||||
export interface RunCommandOptions {
|
||||
cwd?: string;
|
||||
@@ -48,27 +48,18 @@ export function runCommandAsync(
|
||||
let bufferExceeded = false;
|
||||
let timedOut = false;
|
||||
let forceKillTimer: NodeJS.Timeout | null = null;
|
||||
const useProcessGroup = process.platform !== "win32";
|
||||
|
||||
const child = spawn(command, {
|
||||
const supervised = superviseSpawn(command, [], {
|
||||
cwd: options.cwd,
|
||||
env: options.env,
|
||||
detached: useProcessGroup,
|
||||
shell: true,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
maxLifetimeMs: (options.timeoutMs ?? 0) > 0 ? options.timeoutMs! + FORCE_KILL_DELAY_MS + 1_000 : undefined,
|
||||
});
|
||||
const child = supervised.child;
|
||||
|
||||
const signalProcessGroup = (signal: NodeJS.Signals): void => {
|
||||
if (!child.pid) return;
|
||||
try {
|
||||
if (useProcessGroup) {
|
||||
process.kill(-child.pid, signal);
|
||||
} else {
|
||||
child.kill(signal);
|
||||
}
|
||||
} catch {
|
||||
// The command may already have exited and cleaned up its process group.
|
||||
}
|
||||
supervised.kill(signal);
|
||||
};
|
||||
|
||||
const scheduleForceKill = (delayMs: number): void => {
|
||||
|
||||
Reference in New Issue
Block a user