Skip to content

fix: report a gate-lease wait only when the run actually queued - #2375

Merged
cliffhall merged 1 commit into
v2/mainfrom
v2/fix/2369-gate-lease-waited
Sep 14, 2026
Merged

cliffhall merged 1 commit into
v2/mainfrom
v2/fix/2369-gate-lease-waited

Conversation

@cliffhall

Copy link
Copy Markdown
Member

Closes #2369

Problem

runUnderLease measured waited as the wall time of the whole acquireLease call and logged gate-lease: acquired after … (plus the (waited … first) suffix on released after) whenever that was >= pollMs. An uncontended run whose single properLockfile.lock() call was slow — easy on a machine running other gates — therefore reported a wait it never had. That turned two concurrent runs serialize red under load (two acquired after lines, expected one), and made a real gate misreport that it had queued.

Fix

Measure the right thing instead of widening pollMs (#1596):

  • acquireLease now resolves { release, waited }. waited is the time spent looping behind a holder, and 0 whenever the first attempt succeeded, however long that attempt took. The existing announced flag is set on the first failed attempt, so it is exactly "this call looped".
  • Both messages are gated on waited > 0 instead of waited >= pollMs.
  • runUnderLease gains an injectable base fs (default node:fs), which the proper-lockfile guard shim delegates to. It exists for the regression test below.

Tests

New test: an uncontended run whose lock call is slow does not report a wait (#2369). Its mkdir is delayed by 4× pollMs, so the load that caused the flake is reproduced deterministically: no acquired after line, and a released after line with no waited suffix.

Mutation check: with the old measurement restored (waited = whole call, gated on >= pollMs), the new test fails. With the fix, all 21 tests in scripts/gate-lease.test.mjs pass.

npm run local:gate passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_012wBGpf72yP3dJvcz8Y2PbL

acquireLease now returns how long it spent looping behind a holder, and 0
when its first attempt succeeded however long that attempt took. The
"acquired after" line and the "(waited … first)" suffix key off that, so
an uncontended run whose lock call is slow on a loaded machine no longer
claims to have waited, and the "two concurrent runs serialize" test's
count is deterministic under load.

runUnderLease gains an injectable base `fs`, which the new regression
test uses to make an uncontended lock call outlast several polls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012wBGpf72yP3dJvcz8Y2PbL
Signed-off-by: cliffhall <cliff@futurescale.com>
@cliffhall cliffhall added the v2 Issues and PRs for v2 label Sep 14, 2026
@cliffhall
cliffhall requested a balanced review from Copilot September 14, 2026 12:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fix matches #2369 and includes appropriate deterministic regression coverage.

Pull request overview

Fixes gate-lease logging so only genuinely queued runs report waiting.

Changes:

  • Tracks waiting only after a failed lease attempt.
  • Gates acquisition/release wait messages on actual contention.
  • Adds deterministic regression coverage using delayed filesystem access.
File summaries
File Description
scripts/gate-lease.mjs Corrects wait tracking and adds filesystem injection.
scripts/gate-lease.test.mjs Tests slow, uncontended acquisition.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@cliffhall

Copy link
Copy Markdown
Member Author

Copilot review round 1: 0 comments, no suppressed findings, approval recommended — nothing to respond to, so no further round requested. Merging v2/main in next.

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

Labels

v2 Issues and PRs for v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gate-lease: an uncontended run logs "acquired after" when its lock call is slow, failing the "two concurrent runs serialize" test under load

2 participants