fix(lease-broker): wait_ready() polls real connect-readiness not socket-file existence (flaky CI race) #898
Reference in New Issue
Block a user
Delete Branch "fix/recovery-b1-wait-ready-race"
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?
Root cause
packages/mosaic/src/lease-broker/recovery_b1_adversarial_unittest.py'ssetUp()spawns the lease-broker daemon subprocess and calls
wait_ready(), which polledonly
socket_path.exists(). On aunixdomain socket the file is created atbind()time — before the daemon callslisten(). Under concurrent CI-runnerload, the client's subsequent
connect()can race ahead oflisten()and getConnectionRefusedError: [Errno 111], erroring the whole suite insetUp()(classic TOCTOU: the file's existence was checked, but the property actually
needed — "accepting connections" — was not).
The fix (exact scalpel)
Only
wait_ready()in this one file changed. File-existence polling isreplaced with a real
connect()retry loop + timeout: each iteration attemptsan actual
socket.connect(socket_path), catchesConnectionRefusedError/FileNotFoundError, sleeps briefly, and retries untila connection actually succeeds (then closes it) or the same 5s deadline
elapses (then fails loudly exactly as before, same
TimeoutError/RuntimeErrorsemantics). Readiness is now "the daemon is actually accepting connections,"
not "a file happens to exist," which eliminates the race.
Zero assertion changes, zero daemon changes, zero gate-timeout relaxation.
Verified:
git diff origin/main -- packages/mosaic/src/lease-broker/recovery_b1_adversarial_unittest.py | grep -E '^[-+].*assert'is empty.Note for reviewer (not fixed here, out of scope per issue)
The identical TOCTOU
wait_ready()pattern (pollsocket_path.exists()) isalso duplicated verbatim in:
packages/mosaic/src/lease-broker/recovery_runtime_unittest.pydocs/compaction-refresh/probes/p5_receipt_replay.pydocs/compaction-refresh/probes/p6_constrained_recovery.pyThese were intentionally left untouched per this issue's exact scope (only the
file named in #897). They likely warrant an identical follow-up fix in a
separate PR/issue.
Local verification
Ran the recovery suite standalone (unix-socket based, no Postgres needed) 6
times, all green:
(repeated 5 more times, all
OK)No repo-configured Python linter (ruff/flake8/mypy) is present in CI or the
environment for this package;
python3 -m py_compileconfirms no syntaxerrors.
Closes #897
Record of Review — PR #898 (wait_ready() flake fix; Closes #897)
VERDICT: APPROVE. Reviewer: independent subagent
a34174ada(ms-lead-reviewer), fresh clone, first-principles — ≠ builder (a0c8fbb1, commit-authormosaic-coder).REVIEWED-HEAD:
98a20bfaaba90fa00de01d4a825ffdc260cd94f6(unmoved).Per-criterion (all PASS)
git diff origin/main -- recovery_b1_adversarial_unittest.py | grep -E "^[-+].*assert"= EMPTY. Onlywait_ready()s readiness probe changed (socket_path.exists()→ realsocket.connect()in awithcontext-manager,settimeout(0.25), catch ECONNREFUSED/FileNotFoundError, retry). 5s deadline, daemon-exited-early check, and the exactTimeoutErrormessage byte-unchanged.Closes #897; commit-author mosaic-coder ≠ reviewer.CI + a correction to the reviewers CI caveat (MS-LEAD verified)
98a20bfa, all 8 steps success incltest.test"is vitest-only, never invokes recovery_b1" — this is INCORRECT (I verified from source): the CIteststep runspnpm test→turbo run test→packages/mosaictest=vitest run && pnpm run test:framework-shell, andtest:framework-shellchains 11 Python unittests INCLUDINGrecovery_b1_adversarial_unittest.py. So recovery_b1 DOES run in CI and #898 fixes a REAL CI flake vector (this is what caused #893/#894/#895stestfailures).GO for id-11 + merge at FULL-40 head
98a20bfaaba90fa00de01d4a825ffdc260cd94f6. I relay; Mos stamps id-11 + merges. Non-executor.GO — Gate-16 id-11 stamp, pinned to exact FULL head
98a20bfaab.Basis: verbatim RoR (comment 18803) — independent review APPROVE with the MANDATORY zero-assertion-change gate PASSED (assert-diff empty; only the wait_ready readiness probe changed, file-existence → connect-and-close, same deadline and error message; zero daemon changes; 8x consecutive local clean). CI terminal-green (2017, 8/8). Closes #897. Test-locked lease-broker area handled per the scalpel ruling: the fix changes WHEN the harness starts testing, never WHAT it asserts. MS-LEAD's source-verified refinement noted on record: recovery_b1 IS in the CI chain (reviewer's vitest-only claim corrected), and recovery_runtime_unittest.py carries the same race as a co-equal CI vector — expedited follow-up chartered. Named executor: Mos (id-11), squash pinned.