fix(scripts): clamp package candidate timers

This commit is contained in:
Vincent Koc
2026-06-22 02:51:05 +02:00
parent 851b65c060
commit dd89898133
2 changed files with 78 additions and 7 deletions

View File

@@ -26,6 +26,7 @@ const COMMAND_STDOUT_CAPTURE_MAX_CHARS = 8 * 1024 * 1024;
const COMMAND_STDERR_CAPTURE_MAX_CHARS = 128 * 1024;
const COMMAND_TIMEOUT_KILL_AFTER_MS = 5_000;
const COMMAND_PROCESS_TREE_EXIT_POLL_MS = 50;
const MAX_TIMER_TIMEOUT_MS = 2_147_000_000;
const ACTIVE_CHILD_KILLERS = new Set();
const SIGNAL_EXIT_CODES = {
SIGHUP: 129,
@@ -183,8 +184,30 @@ export function resolveNpmPackageCandidatePackRunner(packageSpec, outputDir, par
});
}
function numericTimerValueMs(valueMs) {
const value = Number(valueMs);
return Number.isFinite(value) ? Math.floor(value) : undefined;
}
function resolveTimerTimeoutMs(valueMs, fallbackMs = MAX_TIMER_TIMEOUT_MS) {
const value = numericTimerValueMs(valueMs) ?? numericTimerValueMs(fallbackMs);
return Math.min(Math.max(value ?? MAX_TIMER_TIMEOUT_MS, 1), MAX_TIMER_TIMEOUT_MS);
}
function resolveOptionalTimerTimeoutMs(valueMs) {
if (valueMs === undefined) {
return undefined;
}
return resolveTimerTimeoutMs(valueMs, 1);
}
function run(command, args, options = {}) {
return new Promise((resolve, reject) => {
const resolvedTimeoutMs = resolveOptionalTimerTimeoutMs(options.timeoutMs);
const resolvedKillAfterMs = resolveTimerTimeoutMs(
options.killAfterMs,
COMMAND_TIMEOUT_KILL_AFTER_MS,
);
const useProcessGroup = process.platform !== "win32";
const spawnOptions = {
cwd: options.cwd ?? ROOT_DIR,
@@ -205,21 +228,20 @@ function run(command, args, options = {}) {
const killChild = (signal) => signalChildProcessTree(child, signal, { useProcessGroup });
const terminateChild = () => {
killChild("SIGTERM");
const killAfterMs = options.killAfterMs ?? COMMAND_TIMEOUT_KILL_AFTER_MS;
forceKillAt = Date.now() + killAfterMs;
forceKillAt = Date.now() + resolvedKillAfterMs;
killTimer = setTimeout(() => {
killTimer = undefined;
forceKillAt = undefined;
killChild("SIGKILL");
}, killAfterMs);
}, resolvedKillAfterMs);
};
const timeout =
options.timeoutMs === undefined
resolvedTimeoutMs === undefined
? undefined
: setTimeout(() => {
timedOut = true;
terminateChild();
}, options.timeoutMs);
}, resolvedTimeoutMs);
timeout?.unref?.();
ACTIVE_CHILD_KILLERS.add(killChild);
let stdout = { text: "", truncatedChars: 0 };
@@ -257,14 +279,14 @@ function run(command, args, options = {}) {
}
if (timedOut) {
const timeoutError = new Error(
`${command} ${args.join(" ")} timed out after ${options.timeoutMs}ms`,
`${command} ${args.join(" ")} timed out after ${resolvedTimeoutMs}ms`,
);
if (killTimer) {
void finishTimedOutProcessTree(child, {
forceKillAt,
killChild,
killTimer,
killAfterMs: options.killAfterMs ?? COMMAND_TIMEOUT_KILL_AFTER_MS,
killAfterMs: resolvedKillAfterMs,
useProcessGroup,
}).then(() => reject(timeoutError), reject);
return;