The refused-first-dial red measured: a child's copy of a dropped listener, fixed on main by #566; two issues filed - #591
Conversation
…er's bound This came out of measuring the red of `metaltalk::tests::a_refused_first_dial_is_asked_again_up_to_its_ceiling`: one in 200 full `--lib` runs under load at 9aa473d, panicking at `src/metaltalk.rs:1326:37`. The test is not changed here. At 9aa473d it dialled a listener it had bound and dropped. #566 (e47d1f0) replaced that with a `Refusing` stage before this was measured, so no socket reaches it on main. A standalone probe (bind 127.0.0.1:0, drop, connect_timeout 5 s, 15 s per arm) named the mechanism: - quiet: 72572 dials, all refused. - four threads binding and dropping 127.0.0.1:0 listeners: 87686 dials, all refused, none taken on a binder's port. - eight threads spawning children: 94095 dials, 9 taken. Nothing else in the process held the port, so a child's copy of the listener took them. - no dial timed out in any arm; the slowest refusal was 92 ms. A mutation reinstating the old premise, with a copy of the dropped listener that takes the dial and closes it before a line, fails the test the way the filed red did (build EXIT=0, test EXIT=101, "the dial gave up within 5 s of its 60 and said why", after 5.02 s). The old premise without that copy passes alone (EXIT=0). The wait running out its whole bound is a production path, filed here: `serve` neither redials a first dial closed before a line nor records `unopened`, so `wait_for_connection` waits to its bound, where its doc says it returns once the dial has ended with none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 200-run loop that proved the refused-first-dial test green under load went red once elsewhere. In run 182 of 200 at e3a1cdc, with the 1-minute load average at 62.82, `compiler::tests::a_missing_primary_record_is_refused_and_builds_nothing` failed because its fixture's `git commit` hit "unable to create temporary file: Invalid argument". It is off this branch's path, so it is filed and not investigated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review, round 1, at f4a30b0CI: Diff: Verified against main's code (this worktree, unchanged from main here):
Format, per PR body: no scratchpad path or private-tmp citation ( BLOCKER: none. NOTE: the "Negative control" and probe-table paragraphs describe methodology ("run with REMOVE: none — both issue files are invariant + exit condition, no narration, no dates beyond LAND |
Two issue files. No code changes: the flake this branch was sent to fix was already fixed on main before the work began.
The red, and why no test changes
metaltalk::tests::a_refused_first_dial_is_asked_again_up_to_its_ceilingfailed once in 200 loaded full--libruns at9aa473d0, panicking atsrc/metaltalk.rs:1326:37("the dial gave up within 5 s of its 60 and said why"). At9aa473d0the test bound127.0.0.1:0, dropped the listener, and dialled its port.9aa473d0does not contain #566. #566 (e47d1f06) replaced that premise with aRefusingstage throughReach, so on main no socket reaches the test and there is nothing for a thread or a child to steal. The panic line and column are the same in both versions, which is why the red still looked open.The mechanism, measured
A standalone Rust probe binds
127.0.0.1:0, drops the listener, and runsconnect_timeout(5 s)on that port, for 15 s per arm:127.0.0.1:0CONNECT_WAIT: not seen. No dial timed out, and the slowest refusal took 92 ms.The review's two candidate mechanisms therefore give way to the one
8cc19ef1measured first. #566's commit already carries that finding.Negative control
Each arm is a checked patch on this tree, built, run with
--exact, and reverted. The tree was clean before and after.Stream::connectthroughNet): build EXIT=0, test EXIT=0 when run alone.try_cloneof the listener made before the drop (the child's copy), which accepts the dial and closes it before a line: build EXIT=0, test EXIT=101,panicked at src/metaltalk.rs:1332:37: the dial gave up within 5 s of its 60 and said whyafter 5.02 s. That is the filed red's own message.Loop
The main binary at
e3a1cdc8ran as 200 full--libruns beside acargo test --workspace --exclude toyos-buildloop (load EXIT=0 for each finished run; 1-minute load average 40 to 80). The refused-first-dial test wasokin 200 of 200. The binary exited 0 in 199: run 182 was red in another test, filed here.What this files
issues/diagnostics/a-first-dial-turned-away-before-a-line-is-waited-on-to-its-callers-bound.mdcovers the production path nc2 ran through.serverecords nounopenedfor a first dial closed before a line, sowait_for_connectionwaits out its whole bound, although its doc says it returns once the dial has ended with none.issues/build/a-compiler-fixtures-git-commit-could-not-create-a-temporary-file.mdcovers the red in run 182.a_missing_primary_record_is_refused_and_builds_nothingfailed because its fixture'sgit commitgot "unable to create temporary file: Invalid argument".Gates, at this head
cargo test -p toyos-build --lib: EXIT=0 (412 passed, 3 ignored)cargo run -- --clippy: EXIT=0Unsure
socket()and itsFIOCLEXon macOS. Either way the dial is stolen.🤖 Generated with Claude Code