Repository navigation
Conformance subject for the RFC 0001 relay kit, and graceful draining - #11
Merged
Merged
Conversation
RFC 0001 §14 delegates conformance items 6 and 7 — session-layer direction and state rules, and outcomes under fault — to each implementation's own tests, so a second implementation has nothing shared to be certified against. The relay conformance kit in Miakapp-V3 makes them shared; this is the adapter that lets this relay be its first subject, and it passes all eleven scenarios. The subject prints one LISTENING line, serves RFC 0001 at /ws, accepts a closed set of fixture credentials and applies the profile named by the environment. The fixture verifier lives in this separate main package, so no build of cmd/miakapp-server can contain it. Two rules the fixture set has to mirror, because getting either wrong produces an opaque authentication failure rather than a useful error: a user identity carries no Home Key client binding, and a coordinator or CLI identity carries a client binding and no verified email. Co-Authored-By: Claude Opus 5 <[email protected]>
RFC 0001 §6 gives the session layer a DRAINING state and §7.1 gives the relay GOAWAY to enter it, but nothing here ever entered it. phaseDraining was reachable only in the rule that refuses new requests while draining, so the state machine had a state no code could reach and a shutdown dropped sockets without announcing anything. §12 asks for the opposite: send GOAWAY or FATAL before closing when possible. Drain announces the window to every authenticated session, moves each to DRAINING, and closes whatever is still open when the window expires, so a peer that ignores GOAWAY cannot hold a restart open. The announcement is queued before the phase changes, or the draining rule it installs would refuse the frame that installs it. Draining is one-way, and a session that authenticates mid-window is drained as soon as its bootstrap is on the wire, so nobody slips past the announcement by arriving late. Terminal call frames stay allowed throughout, which is what makes the window worth having: a call already dispatched resolves normally instead of becoming an OUTCOME_UNKNOWN that §8.3 would forbid a client from retrying. The connection registry this needs replaces the bare WaitGroup. Close keeps exactly its previous semantics.
Two additions the expanded corpus needs from its first subject. A drain is the one relay behaviour no peer can request on the wire, so the kit needs an ordered trigger. Under the drain-on-cli profile this subject starts its window when the CLI fixture credential authenticates: no other scenario uses that credential, verification is the one point the subject observes before a session exists, and a short delay keeps the CLI's own WELCOME ahead of the announcement. That beats racing a timer against a twenty-frame prelude. The other addition is a coordinator fixture carrying a different Home Key client binding, so a scenario can show that reauthentication renews authentication material without moving a session to another client. The corpus already covered the home and principal halves of that rule; this completes it. Both live in this separate main package, so no build of cmd/miakapp-server can contain them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to the relay conformance kit in
Miakapp-V3#184. This relay is its first subject, and passes all thirty-seven scenarios.Why
RFC 0001 §14 delegates conformance items 6 and 7 — session-layer direction and state rules, and outcomes under fault — to each implementation's own tests. A second implementation therefore has nothing shared to be certified against for exactly the two items that distinguish a server from a codec.
The subject contract
test/conformance-subjectprints oneLISTENING <ws url>line, serves RFC 0001 at/ws, accepts a closed fixture credential set, applies the profile named byMIAKAPP_CONFORMANCE_PROFILE, and exits cleanly on signal.The fixture verifier lives in this separate
mainpackage, so no build ofcmd/miakapp-servercan contain it.Two rules the fixture set must mirror
Both produce an opaque
authentication failedrather than a useful error when you get them wrong, which cost me a debugging round:The relay change: graceful draining
Writing the corpus's drain scenarios surfaced a real gap rather than a missing test. RFC 0001 §6 gives the session layer a
DRAININGstate, §7.1 gives the relayGOAWAYto enter it, and §12 asks the relay to sendGOAWAYorFATALbefore closing when possible. Here,phaseDrainingwas reachable only inside the rule that refuses new requests while draining — a state no code path could ever reach — so a shutdown dropped sockets without announcing anything.Server.Drainannounces the window to every authenticated session, moves each toDRAINING, and closes whatever is still open when the window expires, so a peer that ignoresGOAWAYcannot hold a restart open. Details worth a reviewer's attention:OUTCOME_UNKNOWNthat §8.3 forbids a client from retrying.WaitGroup.Closekeeps exactly its previous semantics.Four
TestDrain*tests ininternal/relay/drain_test.gopin the window: the announcement and the refusal that follows it, an in-flight call reaching its terminal reply, the deadline close, and a session that authenticates mid-window.Two subject additions the expanded corpus needs
drain-on-cliprofile. A drain is the one relay behaviour no peer can request on the wire, so the kit needs an ordered trigger. This subject starts its window when the CLI fixture credential authenticates: no other scenario uses that credential, verification is the one point the subject observes before a session exists, and a short delay keeps the CLI's ownWELCOMEahead of the announcement — which beats racing a timer against a twenty-frame prelude.Verification
Control for the drain scenarios: built against a subject whose
drainProfilesset is empty, all four fail withtimed out waiting for a frame. The assertions depend on the relay actually sendingGOAWAY, not on the scenario shape.🤖 Generated with Claude Code