Skip to content

fix(workers): let sustained host lateness spend the startup budget - #1321

Open
jorgepb96 wants to merge 1 commit into
mainfrom
fix/responsive-timeout-sustained-lateness
Open

jorgepb96 wants to merge 1 commit into
mainfrom
fix/responsive-timeout-sustained-lateness

Conversation

@jorgepb96

Copy link
Copy Markdown
Owner

Problem

responsiveTimeout (added in #1314) skipped every timer tick that arrived more than 2 × delay late, charging none of its elapsed time to the budget. On a host that is late on every tick, the budget never ran out:

  • CI: with a 30 ms budget on a loaded 4-vCPU runner, nearly every tick lands over 60 ms late, so "an absent child still times out while the parent is responsive" hit its 2 s deadline and failed the v5.16.0 release quality gate (run 40100612862, "Linux tests (6)").
  • Production: under sustained host slowness, a utility process that never spawns was never declared stuck.

Fix

  • A late tick now spends min(elapsed, 2 × delay) instead of nothing, so sustained lateness still uses up the budget, at worst at half the wall-clock rate.
  • If a stall uses up the budget, the child's queued events still get one more tick before expiry. The existing "host stall does not spend the child startup budget" test still passes.
  • The clock and scheduler can be injected (an optional third argument, defaulting to performance.now and the real timers). The only production caller, backgroundProcess.ts, is unchanged.

Tests

Two new deterministic tests in scripts/test-document-work.mjs drive a slow host by hand, with no wall-clock threshold:

  • every tick runs at 3× its delay: the budget still expires, within a bounded amount of host time;
  • one stall that uses up the budget gets exactly one more tick, then expires.

Both fail on the old rule (checked by restoring it temporarily) and pass with the fix. node --test scripts/test-document-work.mjs on Node 22: 6/6 passing, three runs in a row. tsc -p electron/tsconfig.json and eslint on the touched files are clean.

responsiveTimeout skipped every tick that arrived more than twice its
delay late, so a host that was slow on every tick never expired the
budget. On a loaded CI runner the 30 ms test budget never ran out and
the v5.16.0 quality gate failed; in production a child that never
appears was never declared stuck under sustained slowness.

A late tick now spends at most two ticks of budget. A stall that
exhausts the budget still grants the child's events one more tick
before expiry. The clock and scheduler are injectable, and two new
tests drive a slow host by hand with no wall-clock threshold.
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

@jorgepb96, the following checks have failed:

  • Issue linked — failure. Link an existing issue from Development, or add Closes #123 / Fixes #123 to the description when targeting the default branch.

Please resolve the reported failures so that all required checks pass. A maintainer with repository write access can comment retry or /retry to rerun failed CI jobs for the current revision and refresh Issue linked. Editing, reopening, or marking the PR ready for review can retry failed CI once per revision. External checks and CLA acceptance need the resolution described above. New commits run CI automatically.

Latest revision: 170adcee6e0b.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant