src/util/settle.ts — the end-of-run settle bound
Purpose
Section titled “Purpose”A plugin’s flush or teardown is I/O a third party wrote; it must not
hold the run’s exit hostage. This is the deadline every end-of-run
await goes through (plugin-host.ts, telemetry-host.ts), and a
plugin’s telemetry() consultation before the run too (item 921).
teardownTimeoutMs(): number // default 3000settleWithin(p: Promise<unknown>, ms): Promise<boolean>killGraceMs(defaultMs: number): number // VX_KILL_GRACE_MS, else defaultMs-
teardownTimeoutMsreadsVX_TEARDOWN_TIMEOUT_MSper call (a test drives the deadline instead of waiting it out). Out-of-range falls back to the default rather than clamping: this is a BOUND, not a duration — clamping toMAX_TIMEOUT_MSwould honour “wait 24.8 days”, which defeats it, and past the ceiling the delay becomes 1 ms and every flush times out. -
settleWithinreturns true whenpfulfilled before the deadline, false when the deadline won; the caller decides whether a lost result is worth a warning. A rejection before the deadline is not a timeout: it throws, so the caller reports the failure rather than a hang. One landing after the deadline won is swallowed rather than surfacing as an unhandled-rejection crash. -
killGraceMsis the SIGTERM→SIGKILL grace a run grants a child that ignores SIGTERM — the one-shot timeout escalation (exec/runner.ts, 2 s) and the end-of-run persistent shutdown (orchestrator/persistent.ts, 2 s) share it.VX_KILL_GRACE_MSoverrides both, read per call and bounded the same way (zero, garbage and a value past the timer ceiling fall back). It exists for the tests that prove the escalation: each used to wait the full two seconds, a third of the suite’s wall time, for a claim 200 ms proves.
tests/util-settle.test.ts (both deadlines and the grace knob);
tests/timeout-bounds.test.ts.