You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
relay: the invite-mint-plus-CLOSE combination is covered by no test at the wire #983
The invite EVENT plus CLOSE mid-mint, over a socket combination is now covered by no test in the repository, and the only record of that is in a job folder that .git/info/exclude keeps out of every tree.
How the gap arose
a_close_during_the_invite_mint_leaves_the_event_but_not_the_read used to exercise that combination at the wire. It synchronised the CLOSE against the invite mint with a fixed 50 ms sleep, which made a correct fix go red under load (#963), and the test-only fix was to move it down to the handler level: it now owns a Connection and calls unsubscribe::handle directly, ordering the abort before the gate release by program order. That closed the flake and cost the wire path.
What carries what now (verified, not assumed)
piece
covered by
decode of ["CLOSE","invite"], the connection loop, the AUTH exchange
wire tests (wire_parity, transport)
invite EVENT minted before EOSE
an_invite_request_mints_one_kind_28935_event_before_eose — no CLOSE
CLOSE aborting a gated read
a_close_aborts_an_in_flight_read_without_a_frame — see #982, it passes under the delay it exists to catch
mint + CLOSE mid-mint over a socket
nothing
wire_parity's 16 recorded sessions contain invite-mint (no CLOSE) and req-close-abort (CLOSE after the read has ended), and the replay has no gate, so it cannot hold a read open across a CLOSE.
What closing it needs
Shape B from #963's spec: the relay publishes its per-connection registry (relay.rs:291-297), a Server accessor exposes it, and the wire test polls read_in_flight between sending the CLOSE and releasing the gate. That is production source at five Relay::new call sites, one of them nostreamd/src/main.rs:111 — which is why it was not done inside a $1.20 test-only job.
Found while fixing #963 on branch factory/014-close-mint-sync (base rewrite/main @ 2b2287f).
Why the wire-level test was the wrong instrument, not merely an expensive one (recorded here so the next reader learns it from the issue rather than inferring that the wire path vanished):
Once #978 made CLOSE a prefix, handlers::begin runs the whole handler on the connection loop before the next frame is read. A wire-level test that waits for wall-clock time is therefore testing a property the code guarantees by construction, and a timer cannot tell you whether the prefix ran — it can only tell you whether 50 ms was long enough. That is why #963's test moved to the handler level rather than getting a better tolerance, and why the remaining gap is a coverage gap, not a timing one.
What a wire test for this combination would need: the relay publishes its per-connection registry (as it already does internally via read_in_flight), a wire test polls it between the CLOSE and the release of the mint, and the assertion attributes each frame to the subscription whose read produced it. That is production source at five Relay::new sites, which is why it is its own job.
Until then the handler-level test asserts both halves (the invite EVENT is stored, read_in_flight("invite") is false before the release) and its comment names this issue and the sibling wire test.
Activity
chappie-daemon commentedon Oct 25, 2026
Why the wire-level test was the wrong instrument, not merely an expensive one (recorded here so the next reader learns it from the issue rather than inferring that the wire path vanished):
Once #978 made
CLOSEa prefix,handlers::beginruns the whole handler on the connection loop before the next frame is read. A wire-level test that waits for wall-clock time is therefore testing a property the code guarantees by construction, and a timer cannot tell you whether the prefix ran — it can only tell you whether 50 ms was long enough. That is why #963's test moved to the handler level rather than getting a better tolerance, and why the remaining gap is a coverage gap, not a timing one.What a wire test for this combination would need: the relay publishes its per-connection registry (as it already does internally via
read_in_flight), a wire test polls it between theCLOSEand the release of the mint, and the assertion attributes each frame to the subscription whose read produced it. That is production source at fiveRelay::newsites, which is why it is its own job.Until then the handler-level test asserts both halves (the invite
EVENTis stored,read_in_flight("invite")is false before the release) and its comment names this issue and the sibling wire test.