Release closed streams capacity back to connection (#334)
Previously, any streams that were dropped or closed while not having consumed the inflight received window capacity would simply leak that capacity for the connection. This could easily happen if a `RecvStream` were dropped before fully consuming the data, and therefore a user would have no idea how much capacity to release in the first place. This resulted in stalled connections that would never have capacity again.
This commit is contained in:
@@ -334,7 +334,11 @@ impl Recv {
|
||||
capacity: WindowSize,
|
||||
task: &mut Option<Task>,
|
||||
) {
|
||||
trace!("release_connection_capacity; size={}", capacity);
|
||||
trace!(
|
||||
"release_connection_capacity; size={}, connection in_flight_data={}",
|
||||
capacity,
|
||||
self.in_flight_data,
|
||||
);
|
||||
|
||||
// Decrement in-flight data
|
||||
self.in_flight_data -= capacity;
|
||||
@@ -383,6 +387,31 @@ impl Recv {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Release any unclaimed capacity for a closed stream.
|
||||
pub fn release_closed_capacity(
|
||||
&mut self,
|
||||
stream: &mut store::Ptr,
|
||||
task: &mut Option<Task>,
|
||||
) {
|
||||
debug_assert_eq!(stream.ref_count, 0);
|
||||
|
||||
if stream.in_flight_recv_data == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
trace!(
|
||||
"auto-release closed stream ({:?}) capacity: {:?}",
|
||||
stream.id,
|
||||
stream.in_flight_recv_data,
|
||||
);
|
||||
|
||||
self.release_connection_capacity(
|
||||
stream.in_flight_recv_data,
|
||||
task,
|
||||
);
|
||||
stream.in_flight_recv_data = 0;
|
||||
}
|
||||
|
||||
/// Set the "target" connection window size.
|
||||
///
|
||||
/// By default, all new connections start with 64kb of window size. As
|
||||
@@ -515,12 +544,6 @@ impl Recv {
|
||||
});
|
||||
}
|
||||
|
||||
// Update stream level flow control
|
||||
stream.recv_flow.send_data(sz);
|
||||
|
||||
// Track the data as in-flight
|
||||
stream.in_flight_recv_data += sz;
|
||||
|
||||
if stream.dec_content_length(frame.payload().len()).is_err() {
|
||||
trace!("content-length overflow");
|
||||
return Err(RecvError::Stream {
|
||||
@@ -544,6 +567,12 @@ impl Recv {
|
||||
}
|
||||
}
|
||||
|
||||
// Update stream level flow control
|
||||
stream.recv_flow.send_data(sz);
|
||||
|
||||
// Track the data as in-flight
|
||||
stream.in_flight_recv_data += sz;
|
||||
|
||||
let event = Event::Data(frame.into_payload());
|
||||
|
||||
// Push the frame onto the recv buffer
|
||||
|
||||
Reference in New Issue
Block a user