perf(http2): reduce empty EOS frames if end is already known

This commit is contained in:
Sean McArthur
2018-04-18 16:35:53 -07:00
parent a4eb612bd5
commit 38eba1540f
3 changed files with 20 additions and 8 deletions

View File

@@ -191,8 +191,8 @@ impl Error {
Error::new(Kind::Body, Some(cause.into())) Error::new(Kind::Body, Some(cause.into()))
} }
pub(crate) fn new_body_write(cause: io::Error) -> Error { pub(crate) fn new_body_write<E: Into<Cause>>(cause: E) -> Error {
Error::new(Kind::BodyWrite, Some(Box::new(cause))) Error::new(Kind::BodyWrite, Some(cause.into()))
} }
pub(crate) fn new_user_unsupported_version() -> Error { pub(crate) fn new_user_unsupported_version() -> Error {

View File

@@ -64,7 +64,8 @@ where
// parked Connection. // parked Connection.
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
let fut = conn let fut = conn
.map_err(|e| debug!("client h2 connection error: {}", e)) .inspect(|_| trace!("connection complete"))
.map_err(|e| debug!("connection error: {}", e))
.select2(rx) .select2(rx)
.then(|res| match res { .then(|res| match res {
Ok(Either::A(((), _))) | Ok(Either::A(((), _))) |
@@ -132,7 +133,7 @@ where
Ok(Async::Ready(None)) | Ok(Async::Ready(None)) |
Err(_) => { Err(_) => {
trace!("client tx dropped"); trace!("client::dispatch::Sender dropped");
return Ok(Async::Ready(())); return Ok(Async::Ready(()));
} }
} }

View File

@@ -71,14 +71,25 @@ where
// - call self.body_tx.poll_capacity(), return if NotReady // - call self.body_tx.poll_capacity(), return if NotReady
match self.stream.poll_data() { match self.stream.poll_data() {
Ok(Async::Ready(Some(chunk))) => { Ok(Async::Ready(Some(chunk))) => {
trace!("send body chunk: {}B", chunk.as_ref().len()); let is_eos = self.stream.is_end_stream();
self.body_tx.send_data(SendBuf(Some(Cursor::new(chunk))), false) trace!(
.map_err(::Error::new_h2)?; "send body chunk: {} bytes, eos={}",
chunk.as_ref().len(),
is_eos,
);
let buf = SendBuf(Some(Cursor::new(chunk)));
self.body_tx.send_data(buf, is_eos)
.map_err(::Error::new_body_write)?;
if is_eos {
return Ok(Async::Ready(()))
}
}, },
Ok(Async::Ready(None)) => { Ok(Async::Ready(None)) => {
trace!("send body eos"); trace!("send body eos");
self.body_tx.send_data(SendBuf(None), true) self.body_tx.send_data(SendBuf(None), true)
.map_err(::Error::new_h2)?; .map_err(::Error::new_body_write)?;
return Ok(Async::Ready(())); return Ok(Async::Ready(()));
}, },
Ok(Async::NotReady) => return Ok(Async::NotReady), Ok(Async::NotReady) => return Ok(Async::NotReady),