diff --git a/docs/pregate.md b/docs/pregate.md index 9a962cf8e..b6610fe5e 100644 --- a/docs/pregate.md +++ b/docs/pregate.md @@ -448,7 +448,7 @@ test-tier command: runner. Other runners (node --test, vitest, jest, pytest, playwright test, flutter test, dart test, cargo test) get heartbeats only. A heartbeat follows each 60 s with no progress line; - is killed as **stalled** when its log does not grow and its process group - uses no CPU for the stall timeout (`--stall-timeout `, else + stays under a tenth of one CPU for the stall timeout (`--stall-timeout `, else `stall_timeout_s`, else 300; `0` disables): the check is `incomplete` with `PREGATE_STALLED` and names the last file started; the next serial file still runs. The group counts as busy when its CPU time, sampled each second, diff --git a/lib/pregate/supervise.ts b/lib/pregate/supervise.ts index 3c4c3412e..37cc3210e 100644 --- a/lib/pregate/supervise.ts +++ b/lib/pregate/supervise.ts @@ -220,10 +220,8 @@ export function supervise(o: SuperviseOptions): Promise { if (now >= o.deadline) { stop('timeout'); return; } if (o.stallMs > 0 && process.platform !== 'win32' && now - cpu.at >= CPU_SAMPLE_MS) { const used = groupCpuMs(child.pid!); - if (used !== null) { - if (used - cpu.ms >= CPU_BUSY_SHARE * (now - cpu.at)) lastBusy = now; - cpu = { at: now, ms: used }; - } + if (used !== null && used - cpu.ms >= CPU_BUSY_SHARE * (now - cpu.at)) lastBusy = now; + cpu = { at: now, ms: used ?? cpu.ms }; } if (o.stallMs > 0 && now - Math.max(lastGrowth, lastBusy) >= o.stallMs) { stop('stalled'); return; } if (now - lastProgress < heartbeatMs) return;