Skip to content

Commit 4cbb929

Browse files
authored
perf(http2): reserve minimal send capacity when piping request bodies (#4149)
Reserving the full chunk length makes every in-flight stream a heavyweight claimant in the connection-window distribution for as long as it waits for capacity, which is costly once the streams sharing a connection collectively demand more than the window the peer advertises. The chunk is still only reserved against once it is in hand, so capacity can never be pinned by a body that produces nothing (#4003). h2 raises the requested send capacity to the buffered length inside `send_data`, so the demand eventually signalled to the peer is unchanged; only the transient claim held while the stream waits for its first byte of capacity differs.
1 parent 8a98d13 commit 4cbb929

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

src/proto/h2/mod.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,21 @@ where
216216
continue;
217217
}
218218

219-
// Reserve exactly the chunk size so we never pin more
220-
// connection-level flow-control window than we are
221-
// about to consume. Stash the chunk in `self` so it
222-
// survives the upcoming `poll_capacity` wait even if
223-
// it returns `Poll::Pending`.
224-
me.body_tx.reserve_capacity(len);
219+
// Reserve a minimal claim on the connection-level
220+
// flow-control window rather than the whole chunk. The
221+
// chunk is already in hand, so this still cannot pin
222+
// capacity against a body that never produces data
223+
// (#4003), and h2 raises the request to the buffered
224+
// length inside `send_data`, so the demand eventually
225+
// signalled to the peer is unchanged. Claiming the full
226+
// length up front instead makes every in-flight stream a
227+
// heavyweight claimant while it waits, which is costly
228+
// once the streams on a connection collectively demand
229+
// more than the window the peer advertises. Stash the
230+
// chunk in `self` so it survives the upcoming
231+
// `poll_capacity` wait even if it returns
232+
// `Poll::Pending`.
233+
me.body_tx.reserve_capacity(1);
225234
*me.buffered_data = Some(Peeked {
226235
data: chunk,
227236
is_eos,

0 commit comments

Comments
 (0)