test(wake): #923 de-flake T10 concurrent-enqueue race (deterministic barrier) #926
Reference in New Issue
Block a user
Delete Branch "fix/wake-923-t10-deflake"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #923; Part of #892
The race (diagnosed)
T10 launched its two concurrent
store.sh enqueuecalls with plaincmd & cmd & wait "$p1"; wait "$p2". Nothing guaranteed the two children wereever genuinely in-flight together — the scheduler is free to run one to
completion before the other is even forked, so the flock contention T10 exists
to prove was sometimes never really exercised. Under CI load this manifested
as the intermittent fail-then-pass-on-rerun behavior in #923.
The fix (test determinism only, invariant unchanged)
Added a deterministic start barrier (an
flock'd gate file — nosleep):lock on a gate file the parent holds exclusively;
both children are truly launched and blocked;
shared-lock acquisitions are granted together and they race into
store.sh's own enqueue lock for real, at (as close to) the same instant asthe scheduler allows.
Assertions are unchanged: distinct + gapless
{1,2}seqs (order-independent),both durably enqueued (
pending_depth=2), only after both PIDs have exited.Verification (all foreground)
test-wake-store-ack.shpass (previouslyintermittent).
_wake_lock_acquiretemporarily stubbed to a no-op(uncommitted, local-only mutation, reverted after), T10 reliably aliases
(both enqueues get seq
1) and fails loud, 5/5 runs — proving thede-flaked T10 still catches a real aliasing regression. Restored and
reconfirmed GREEN.
pnpm run test:framework-shell: rc=0 normally, and rc=0 withopensslmasked from
PATH(command -v opensslverified empty in that run).shellcheck0.11.0: clean.git diff --stat: onlytest-wake-store-ack.sh(no manifest bump — testdeterminism only, no behavior change, matching #918/#861 precedent).
Note for follow-up (out of scope for this PR)
While diagnosing, I found and deterministically reproduced (100% repeatable,
independent of test-file timing) a genuine product-level TOCTOU race,
separate from the test-harness issue this PR fixes:
_wake_clean_stale_tmp()(_wake-common.sh) unconditionallyfind -deletes every.wake.tmp.*file in the state dir. It's invoked by_wake_init_dir(), whichcmd_enqueuecalls atstore.sh:166— before_wake_lock_acquireatstore.sh:174. So a second enqueue process, still inits pre-lock setup, can delete a first process's live in-flight atomic-write
temp file even while that first process holds the enqueue lock the entire
time, causing a spurious "durable pending write FAILED" abort. Reproduced
deterministically by holding the lock + creating a tmp file in one process
while a concurrent process runs
_wake_init_dir()with no lock at all.This can plausibly account for at least some of the real-world T10 CI flake
history (not just the test-harness timing gap fixed here), and is a genuine
concurrent-enqueue reliability issue independent of any test. Recommend a
follow-up: move the pre-lock
_wake_init_dircleanup either inside theenqueue lock, or restrict
_wake_clean_stale_tmpto non-hot-path callers(e.g.
cmd_initonly) rather than running it unconditionally on everycmd_enqueueinvocation. I did not touchstore.sh/_wake-common.shin thisPR to keep the diff scoped to the test-determinism fix as directed.
T10 ("two concurrent store.sh enqueue get DISTINCT seqs via flock") launched its two background enqueues with plain `cmd & cmd & wait` — no guarantee the scheduler ever actually overlapped them, so the flock contention the test exists to prove was sometimes never really exercised (or the assertion could race a not-yet-durable second write), producing an intermittent CI-load flake. Replace the launch with a deterministic start barrier (flock'd gate file, no sleep): both children signal a ready marker then block on a shared exclusive lock; the parent busy-polls (not sleeps) until both markers exist, THEN releases the gate so both children's pending shared-lock waits are granted together and they race into store.sh's own enqueue lock for real. Assertions (distinct+gapless {1,2} seqs, order-independent, both durably enqueued) are unchanged and still run only after both PIDs have exited. Verified: 30/30 sequential foreground runs pass (previously intermittent). RED-catch reproduced 5/5: with _wake_lock_acquire temporarily stubbed to a no-op, T10 reliably aliases (both enqueues get seq '1') and fails loud, proving the de-flaked test still catches a real aliasing regression; restored and reconfirmed GREEN. shellcheck 0.11.0 clean. Closes #923; Part of #892Record of Review — PR #926 (issue #923): T10 concurrency-test de-flake — FINAL, CI-GREEN
VERDICT: APPROVE — GO. REVIEWED-HEAD (full-40):
f9175c99b6b8e1be51ee6aa6edec5f910d43e02d. CI: TERMINAL-GREEN (pipeline 2072).Review basis
Independent reviewer
ae6831d2(≠ buildermosaic-coder) — APPROVE, all 4 criteria PASS, reproduced (not narrative):f9175c99…; mergeable; PR-author id2 ≠ commit-authormosaic-coder; bodyCloses #923+Part of #892; delta = ONLY test-wake-store-ack.sh (+50/-5); store.sh/_wake-common.sh BYTE-UNCHANGED vs main (no product touch); no manifest bump (test-only, #918/#861 precedent).cmd & cmd & waitnever guaranteeing both enqueues concurrently in-flight; fix = deterministic flock START BARRIER (no sleep; both children block on a shared lock, parent busy-polls until both ready-markers then releases → both race into store.shs enqueue lock together). Reviewer ran the harness 30× → 30/30 pass; assertions (distinct+gapless {1,2}, order-independent, both durable) unchanged._wake_lock_acquireto no-op → T10 RED 5/5 (both alias seq 1); reverted → GREEN. Still catches a real flock/aliasing regression.command -v opensslempty, HMAC groups SKIP); firewall 0; diff test-only.Non-blocking observations
(a) a small ready-marker/flock ordering window (proven fine by 30/30 + 5/5); (b) spin-cap magic number (fires sub-second). Neither blocks.
Important context (separate, tracked)
The builder deterministically reproduced + PROMINENTLY DISCLOSED a genuine product-level enqueue TOCTOU (
_wake_clean_stale_tmppre-lock) — correctly OUT OF SCOPE for this test-only PR (store.sh untouched) — filed + Mos-ELEVATED as #927 (fix in flight). Scope discipline exemplary.6-check — GO
f9175c99b6b8e1be51ee6aa6edec5f910d43e02d✓ · 3. reviewer(ae6831d2)≠builder durable RoR ✓ · 4. reviewed==CI==merge-head allf9175c99✓ · 5. bodyCloses #923+Part of #892✓ · 6. queue-guard at merge.GO for id-11 + squash-merge at FULL-40
f9175c99b6b8e1be51ee6aa6edec5f910d43e02d. Closes #923. NOTE: #927 (in flight) may add a store-ack test group → union-rebase #927 onto the new main after this merge if so. Non-executor.GO — Gate-16 id-11 stamp, pinned to exact FULL head
f9175c99b6.Basis: verbatim FINAL RoR (comment 19171) — independent review APPROVE 4/4: determinism reproduced 30/30 via the flock start-barrier, the flock-disabled RED preserved 5/5 (the aliasing catch keeps its teeth), store.sh and _wake-common byte-unchanged (test-only). CI terminal-green. Closes #923 — the T10 timing-granularity flake joins T7 in the fixed column, and this de-flake's build is also what surfaced #927 (the builder's scope discipline turning a test fix into a tracked product-correctness find). Part of #892. Named executor: Mos (id-11), squash pinned.