feat(h2): implement flow control for h2 bodies

Closes #1548
This commit is contained in:
Steven Fackler
2018-06-11 11:32:50 -07:00
committed by Sean McArthur
parent 386fc0d70b
commit 1c3fbfd6bf

View File

@@ -103,20 +103,21 @@ where
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
loop { loop {
if !self.data_done { if !self.data_done {
// TODO: make use of flow control on SendStream // we don't have the next chunk of data yet, so just reserve 1 byte to make
// If you're looking at this and thinking of trying to fix this TODO, // sure there's some capacity available. h2 will handle the capacity management
// you may want to look at: // for the actual body chunk.
// https://docs.rs/h2/0.1.*/h2/struct.SendStream.html self.body_tx.reserve_capacity(1);
//
// With that doc open, we'd want to do these things: if self.body_tx.capacity() == 0 {
// - check self.body_tx.capacity() to see if we can send *any* data loop {
// - if > 0: match try_ready!(self.body_tx.poll_capacity().map_err(::Error::new_h2)) {
// - poll self.stream Some(0) => {}
// - reserve chunk.len() more capacity (because its about to be used)? Some(_) => break,
// - send the chunk None => return Err(::Error::new_canceled(None::<::Error>)),
// - else: }
// - try reserve a smallish amount of capacity }
// - call self.body_tx.poll_capacity(), return if NotReady }
match try_ready!(self.stream.poll_data().map_err(|e| self.on_err(e))) { match try_ready!(self.stream.poll_data().map_err(|e| self.on_err(e))) {
Some(chunk) => { Some(chunk) => {
let is_eos = self.stream.is_end_stream(); let is_eos = self.stream.is_end_stream();
@@ -136,6 +137,7 @@ where
} }
} }
None => { None => {
self.body_tx.reserve_capacity(0);
let is_eos = self.stream.is_end_stream(); let is_eos = self.stream.is_end_stream();
if is_eos { if is_eos {
return self.send_eos_frame().map(Async::Ready); return self.send_eos_frame().map(Async::Ready);