test: stabilize perf-316 lock-holder holdMs race under load
Worker A (lock holder) used holdMs=1000 as a safety cap on its
Atomics.wait for the writer's contention signal. Under container load
(full suite, node24) Worker B's spawn + require('state.cjs') + stub
installation can exceed 1s, so A's wait timed out and removed the lock
before B ever contended. B's first atomic-create then succeeded
(lockAttempts:1), failing the retry-path witness and red-flagging the
gsd-test gate on otherwise-green branches.
The handshake is the real release trigger; holdMs is only a safety cap
for a dead/hung writer, so it must be large enough to never elapse
during B's spawn+init. Bump to 30s (bounded; afterEach terminate()s A
on the normal path, so no added latency) and widen the per-test timeout
to 15s for spawn headroom under heavy parallel load.
This commit is contained in:
@@ -173,14 +173,21 @@ describe('perf #316: acquireStateLock hoists sleep buffer — exactly one SAB pe
|
||||
|
||||
test(
|
||||
'sabCount === 1 after a call that undergoes >= 1 retry (post-fix assertion)',
|
||||
{ timeout: 8000 },
|
||||
{ timeout: 15000 },
|
||||
async () => {
|
||||
// ── Worker A: hold the lock for 1000ms ─────────────────────────────────
|
||||
// ── Worker A: hold the lock until the writer signals contention ─────────
|
||||
// The holder releases the lock only when the writer signals its first
|
||||
// failed lock attempt (see WRITER_WORKER_CODE), so the writer is guaranteed
|
||||
// to contend at least once regardless of worker-spawn latency. holdMs is now
|
||||
// only a safety cap in case that signal never arrives.
|
||||
const holdMs = 1000;
|
||||
// to contend at least once. holdMs is ONLY a safety cap for a dead/hung
|
||||
// writer — it MUST be large enough that it never elapses while Worker B is
|
||||
// still spawning + requiring state.cjs + installing its stubs. Under load
|
||||
// (full suite in a container) that spawn+init can exceed 1s; a 1s cap let A
|
||||
// time out and remove the lock before B contended, so B's first openSync
|
||||
// succeeded (lockAttempts:1) and the retry-path witness failed. 30s is
|
||||
// comfortably beyond B's worst-case init yet still bounded; the test's own
|
||||
// timeout caps wall-clock, and afterEach terminate()s A the moment B posts
|
||||
// its result, so the normal path adds no delay.
|
||||
const holdMs = 30000;
|
||||
const releaseSab = new SharedArrayBuffer(4);
|
||||
let resolveLockWritten;
|
||||
const lockWritten = new Promise((resolve) => { resolveLockWritten = resolve; });
|
||||
|
||||
Reference in New Issue
Block a user