fix: report a gate-lease wait only when the run actually queued (#2369)
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>
This commit is contained in:
parent
fd6e60148b
commit
d76a67f874
1 changed files with 55 additions and 16 deletions
|
|
@ -8,6 +8,7 @@
|
|||
import { after, test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { spawn } from "node:child_process";
|
||||
import nodeFs from "node:fs";
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
|
|
@ -231,6 +232,28 @@ test("two concurrent runs serialize: the second starts after the first ends", as
|
|||
assert.ok(!existsSync(leaseTarget(dir)), "the holder record goes with it");
|
||||
});
|
||||
|
||||
test("an uncontended run whose lock call is slow does not report a wait (#2369)", async () => {
|
||||
const dir = freshDir();
|
||||
const { lines, log } = collectLog();
|
||||
const pollMs = 25;
|
||||
// A loaded machine, made deterministic: the lock directory's creation
|
||||
// alone outlasts several polls, though nobody else holds the lease.
|
||||
const slowFs = {
|
||||
...nodeFs,
|
||||
mkdir: (p, cb) => setTimeout(() => nodeFs.mkdir(p, cb), pollMs * 4),
|
||||
};
|
||||
assert.equal(await runNode("", { dir, log, pollMs, fs: slowFs }), 0);
|
||||
assert.deepEqual(
|
||||
lines.filter((l) => l.startsWith("gate-lease: acquired after")),
|
||||
[],
|
||||
);
|
||||
const released = lines.filter((l) =>
|
||||
l.startsWith("gate-lease: released after"),
|
||||
);
|
||||
assert.equal(released.length, 1);
|
||||
assert.doesNotMatch(released[0], /waited/);
|
||||
});
|
||||
|
||||
test("the child's exit code is the run's exit code", async () => {
|
||||
const dir = freshDir();
|
||||
assert.equal(await runNode("process.exit(7)", { dir, log: () => {} }), 7);
|
||||
|
|
|
|||
Loading…
Reference in a new issue