refactor(server): make dispatch routing and failure paths explicit - #4036
Open
hubcio wants to merge 2 commits into
Open
refactor(server): make dispatch routing and failure paths explicit#4036hubcio wants to merge 2 commits into
hubcio wants to merge 2 commits into
Conversation
The TCP dispatch funnel hid its rules in control flow: seven ordered if-return probes where the order was the only spec, two rewrite chains written out inline in two places, twenty send sites each picking a failure channel by whichever builder they called, two client-request handlers on shard 0 with separate queues, and a read gate that let unknown codes fall through to a catch-all. Each is now written down once. classify() returns a RequestClass that handle_client_request matches on, so the order of checks inside classify is the routing. rewrite.rs holds both rewrite chains as pure functions. dispatch/failure.rs holds the failure channel table and the one exit every host-built frame takes. Each shard builds one client-request handler that shard 0's transports share, dropping the duplicate queues, the double hook install and a reference cycle that leaked the shard. The read gate now decides every code in the command table instead of passing unlisted ones to the builder's empty-ok. Tests pin the probe order, each channel's bytes, and every table entry. Removing the cycle exposed a shutdown bug it had hidden: shard 0 owns the only write handle to the metadata state machine and could drop it while peers were still reading, panicking their pumps. Peers now count themselves out once their runtime is gone, and shard 0 waits for that, bounded by shutdown_join_timeout.
The consumer-group Join/Leave rewrite failed silently: the funnel logged and returned, sending nothing. Its only error is an undecodable body, so there is nothing for the client to replay and the SDK's lockstep connection waits out its read timeout before it learns anything. Send the typed pre-consensus deny the rest of the funnel already uses. Rename FailureChannel to FrameChannel while the type is still new. It labels every host-built frame, success replies included, so the old name contradicted most of its call sites. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XYs1ovuT73HVJHXhW9b5at
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #4036 +/- ##
============================================
+ Coverage 85.12% 85.21% +0.09%
Complexity 1402 1402
============================================
Files 1236 1238 +2
Lines 181607 182489 +882
Branches 147900 148782 +882
============================================
+ Hits 154596 155514 +918
+ Misses 22957 22911 -46
- Partials 4054 4064 +10
🚀 New features to boost your workflow:
|
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.
The TCP dispatch funnel hid its rules in control flow: seven
ordered if-return probes where the order was the only spec, two
rewrite chains written out inline in two places, twenty send
sites each picking a failure channel by whichever builder they
called, two client-request handlers on shard 0 with separate
queues, and a read gate that let unknown codes fall through to a
catch-all.
Each is now written down once. classify() returns a RequestClass
that handle_client_request matches on, so the order of checks
inside classify is the routing. rewrite.rs holds both rewrite
chains as pure functions. dispatch/failure.rs holds the failure
channel table and the one exit every host-built frame takes. Each
shard builds one client-request handler that shard 0's transports
share, dropping the duplicate queues, the double hook install and
a reference cycle that leaked the shard. The read gate now
decides every code in the command table instead of passing
unlisted ones to the builder's empty-ok. Tests pin the probe
order, each channel's bytes, and every table entry.
Removing the cycle exposed a shutdown bug it had hidden: shard 0
owns the only write handle to the metadata state machine and
could drop it while peers were still reading, panicking their
pumps. Peers now count themselves out once their runtime is gone,
and shard 0 waits for that, bounded by shutdown_join_timeout.