perf(http2): less eager server polls since it hurts parallel flushing

This commit is contained in:
Sean McArthur
2018-10-24 15:35:11 -07:00
parent 6005827c3e
commit b20971cb4e
2 changed files with 50 additions and 10 deletions

View File

@@ -33,6 +33,13 @@ fn http1_post(b: &mut test::Bencher) {
});
}
#[bench]
fn http1_get_parallel(b: &mut test::Bencher) {
bench_parallel_with(b, Version::HTTP_11, || {
Request::new(Body::empty())
});
}
#[bench]
fn http2_get(b: &mut test::Bencher) {
bench_with(b, Version::HTTP_2, || {
@@ -49,10 +56,18 @@ fn http2_post(b: &mut test::Bencher) {
});
}
#[bench]
fn http2_get_parallel(b: &mut test::Bencher) {
bench_parallel_with(b, Version::HTTP_2, || {
Request::new(Body::empty())
});
}
fn bench_with<F>(b: &mut test::Bencher, version: Version, make_request: F)
where
F: Fn() -> Request<Body>,
{
let _ = pretty_env_logger::try_init();
let mut rt = Runtime::new().unwrap();
let body = b"Hello";
let addr = spawn_hello(&mut rt, body);
@@ -76,6 +91,39 @@ where
});
}
fn bench_parallel_with<F>(b: &mut test::Bencher, version: Version, make_request: F)
where
F: Fn() -> Request<Body>,
{
let _ = pretty_env_logger::try_init();
let mut rt = Runtime::new().unwrap();
let body = b"Hello";
let addr = spawn_hello(&mut rt, body);
let connector = HttpConnector::new(1);
let client = hyper::Client::builder()
.http2_only(version == Version::HTTP_2)
.build::<_, Body>(connector);
let url: hyper::Uri = format!("http://{}/hello", addr).parse().unwrap();
b.bytes = body.len() as u64;
b.iter(move || {
let futs = (0..10)
.into_iter()
.map(|_| {
let mut req = make_request();
*req.uri_mut() = url.clone();
client.request(req).and_then(|res| {
res.into_body().for_each(|_chunk| {
Ok(())
})
}).map_err(|_e| ())
});
let _ = rt.block_on(::futures::future::join_all(futs));
});
}
fn spawn_hello(rt: &mut Runtime, body: &'static [u8]) -> SocketAddr {
use hyper::service::{service_fn};
let addr = "127.0.0.1:0".parse().unwrap();

View File

@@ -134,17 +134,9 @@ where
let req = req.map(|stream| {
::Body::h2(stream, content_length)
});
let mut fut = H2Stream::new(service.call(req), respond);
// try to eagerly poll the future, so that we might
// not need to allocate a new task...
match fut.poll() {
Ok(Async::Ready(())) | Err(()) => (),
Ok(Async::NotReady) => {
let fut = H2Stream::new(service.call(req), respond);
exec.execute_h2stream(fut)?;
}
}
}
// no more incoming streams...
trace!("incoming connection complete");