feat(http2): add adaptive window size support using BDP (#2138)
This adds support for calculating the Bandwidth-delay product when using HTTP2. When a DATA frame is received, a PING is sent to the remote. While the PING acknoledgement is outstanding, the amount of bytes of all received DATA frames is accumulated. Once we receive the PING acknowledgement, we calculate the BDP based on the number of received bytes and the round-trip-time of the PING. If we are near the current maximum window size, the size is doubled. It's disabled by default until tested more extensively.
This commit is contained in:
@@ -12,6 +12,7 @@ use http::HeaderMap;
|
||||
use http_body::{Body as HttpBody, SizeHint};
|
||||
|
||||
use crate::common::{task, watch, Future, Never, Pin, Poll};
|
||||
use crate::proto::h2::bdp;
|
||||
use crate::proto::DecodedLength;
|
||||
use crate::upgrade::OnUpgrade;
|
||||
|
||||
@@ -61,6 +62,11 @@ struct Extra {
|
||||
/// connection yet.
|
||||
delayed_eof: Option<DelayEof>,
|
||||
on_upgrade: OnUpgrade,
|
||||
|
||||
/// Records bytes read to compute the BDP.
|
||||
///
|
||||
/// Only used with `H2` variant.
|
||||
h2_bdp: bdp::Sampler,
|
||||
}
|
||||
|
||||
type DelayEofUntil = oneshot::Receiver<Never>;
|
||||
@@ -175,11 +181,21 @@ impl Body {
|
||||
Body { kind, extra: None }
|
||||
}
|
||||
|
||||
pub(crate) fn h2(recv: h2::RecvStream, content_length: DecodedLength) -> Self {
|
||||
Body::new(Kind::H2 {
|
||||
pub(crate) fn h2(
|
||||
recv: h2::RecvStream,
|
||||
content_length: DecodedLength,
|
||||
bdp: bdp::Sampler,
|
||||
) -> Self {
|
||||
let mut body = Body::new(Kind::H2 {
|
||||
content_length,
|
||||
recv,
|
||||
})
|
||||
});
|
||||
|
||||
if bdp.is_enabled() {
|
||||
body.extra_mut().h2_bdp = bdp;
|
||||
}
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
pub(crate) fn set_on_upgrade(&mut self, upgrade: OnUpgrade) {
|
||||
@@ -204,6 +220,7 @@ impl Body {
|
||||
Box::new(Extra {
|
||||
delayed_eof: None,
|
||||
on_upgrade: OnUpgrade::none(),
|
||||
h2_bdp: bdp::disabled(),
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -262,6 +279,9 @@ impl Body {
|
||||
Some(Ok(bytes)) => {
|
||||
let _ = h2.flow_control().release_capacity(bytes.len());
|
||||
len.sub_if(bytes.len() as u64);
|
||||
if let Some(ref extra) = self.extra {
|
||||
extra.h2_bdp.sample(bytes.len());
|
||||
}
|
||||
Poll::Ready(Some(Ok(bytes)))
|
||||
}
|
||||
Some(Err(e)) => Poll::Ready(Some(Err(crate::Error::new_body(e)))),
|
||||
|
||||
Reference in New Issue
Block a user