Repository navigation
Conversation
poll_ready only needs the buffer written out to free capacity, so it now calls a new write_out (the write loop split out of flush) instead of flush. flush still writes out and then flushes the transport, and Streams::poll_complete still flushes once every pending frame is buffered. While a DATA frame is queued the codec has no capacity, so poll_ready ran before every DATA frame and flushed the transport once per frame. Assisted-by: Claude:Opus-5.5
AzulEterno
added a commit
to AzulEterno/hyper-h2-edge
that referenced
this pull request
Nov 6, 2026
Carry the optional validated WriteBatchSize API and lazy full-frame batching. Integrate hyperium#980 (c8bfb22) while preserving stable flush boundaries. Include protocol regressions and upstream attribution; omit hyperium#998 after matched local benchmarks.
This branch has not been deployed
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.
FramedWrite::poll_readycallsflush, which writes the buffered frame and then callspoll_flushon the transport. While a DATA frame is queued asnext, the codec has no capacity, sopoll_readyruns before every DATA frame. A large response therefore flushes the transport once per frame.poll_readyonly needs the buffer written out to free capacity. This change splits the write loop out offlushintowrite_out, andpoll_readycalls only that.flushstill writes out and then flushes. The transport is still flushed once every pending frame is buffered (Streams::poll_completecallsflush), so nothing is held back.A transport that does work per flush pays it per frame. With kernel TLS (kTLS), each write ends a TLS record. A 16,393-byte frame (9-byte header plus 16 KiB of data) then goes out as one full record and one 9-byte record, which doubles the record count and the AEAD operations. With this change, a transport that gathers writes until
poll_flushcan send whole records. On a 2 GB HTTP/2 download over loopback (i7-9700K), the server's CPU per GB fell from 0.850 s to 0.715 s on kTLS, and from 0.690 s to 0.655 s on rustls. Transports that write on everypoll_writebehave as before.