Repository navigation
perf(h1): reuse one pipe per connection for spliced bodies - #154
Merged
Merged
Conversation
A writer whose socket can splice now polls the body it sends with a PipeOffer carrying the pipe its last pipe frame left, and the connection keeps that pipe between messages. A received body hands the offer back with its end, including one queued behind the last frame without a demand, and a splice that finds the end of the stream returns its empty pipe. A body forwarded from one connection to another therefore costs one pipe per connection instead of a pipe2 and two closes per frame, and a forwarder between them no longer has to offer on the writer's behalf. Closes #142
A forwarder passes its consumer's offer, or its absence, straight through instead of matching on it to choose poll_next.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced Nov 11, 2026
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 h1 server and client writers now poll the body they send with a
PipeOffer. They only do this when the writer can splice. The offer carries the pipe the connection drained last, andOutboxkeeps it between messages. The client'sOutboxnow lives onConnection. A forwarded body therefore uses one pipe per connection instead of apipe2and twocloses per frame.IncomingBodyused to strand the offer and its pipe at the end of every body. It now takes back an unanswered demand when the body ends, andtry_splicereturns the empty pipe to the offer when it finds EOF. h3 never offers, so it gets plain data frames. Before, it read back a pipe a forwarder had made.Body::poll_frame_offeringnow takesOption<&mut PipeOffer>, whereNonemeanspoll_next. A forwarder passes its consumer's offer straight through instead of matching on it.New splice tests run on compio and tokio. They count pipes by inode in
/proc/self/fdand check that two keep-alive requests echoed through a pass-through forwarder share one pipe over more than four splices, and that a client reuses its drained pipe. The tests fail with the reattach removed. The kTLS splice-out path needs CI.Closes #142