fix(infra): clamp restart deferral poll

This commit is contained in:
Peter Steinberger
2026-05-30 15:41:12 -04:00
parent 3a31b34151
commit de1c4f8aec
2 changed files with 19 additions and 2 deletions

View File

@@ -66,6 +66,23 @@ describe("deferGatewayRestartUntilIdle timeout", () => {
expect(hooks.onTimeout).toHaveBeenCalledOnce();
});
it("clamps oversized poll intervals instead of polling immediately", () => {
const hooks: RestartDeferralHooks = {
onReady: vi.fn(),
};
let pending = 1;
deferGatewayRestartUntilIdle({
getPendingCount: () => pending,
pollMs: Number.MAX_SAFE_INTEGER,
hooks,
});
pending = 0;
vi.advanceTimersByTime(1);
expect(hooks.onReady).not.toHaveBeenCalled();
});
it("carries timeout restart intent when the deferral budget is exhausted", () => {
const hooks: RestartDeferralHooks = {
onTimeout: vi.fn(),

View File

@@ -9,6 +9,7 @@ import {
resolveGatewaySystemdServiceName,
} from "../daemon/constants.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { resolveTimerTimeoutMs } from "../shared/number-coercion.js";
import { replaceFileAtomicSync } from "./replace-file.js";
import { cleanStaleGatewayProcessesSync, findGatewayPidsOnPortSync } from "./restart-stale-pids.js";
import type { RestartAttempt } from "./restart.types.js";
@@ -494,8 +495,7 @@ export function deferGatewayRestartUntilIdle(opts: {
reason?: string;
timeoutIntent?: GatewayRestartIntent;
}): void {
const pollMsRaw = opts.pollMs ?? DEFAULT_DEFERRAL_POLL_MS;
const pollMs = Math.max(10, Math.floor(pollMsRaw));
const pollMs = resolveTimerTimeoutMs(opts.pollMs, DEFAULT_DEFERRAL_POLL_MS, 10);
const maxWaitMs =
typeof opts.maxWaitMs === "number" && Number.isFinite(opts.maxWaitMs) && opts.maxWaitMs > 0
? Math.max(pollMs, Math.floor(opts.maxWaitMs))