Closed johndoe52 closed 5 years ago
https://github.com/hyperium/hyper/issues/1657
To extract body from response
add use hyper::rt::Stream;
Box::new(CLIENT.request(req)
.and_then(move |res| {
count.fetch_add(1, Ordering::SeqCst);
if res.status().is_success() {
// book page fetched, do whatever with res.body()
// ...
//
tokio::spawn(fetch_page(count, book, page + 1));
return res.into_body().concat2() // returns a future, resolved in .map
} else if res.status().as_u16() == 429 {
// server sends rate limit ms in retry-after if it wants us to slow down
// should actually synchronize this with tokio and make tokio pause execution
// of futures for that time
tokio::spawn(tokio_timer::sleep(
time::Duration::from_millis(res.headers()
.get("retry-after").unwrap().to_str().unwrap()
.parse().unwrap()))
.and_then(move |_| {
tokio::spawn(fetch_page(count, book, page));
ok(())
}).map_err(|_| {}));
ok(())
} else if res.status().as_u16() == 404 {
// book pages fetched
println!("book {} fetched", book);
ok(())
} else if res.status().is_server_error() {
// server error, retrying
tokio::spawn(fetch_page(count, book, page));
ok(())
} else {
println!("unhandled status: {} book: {}", res.status().as_u16(), book);
ok(())
}
}).map(|body| {
println!("body: {}", ::std::str::from_utf8(&body).unwrap()); // prints downloaded body here
}).map_err(move |e| {
eprintln!("{}", e);
}))
hyper's Client
does not limit how many outstanding requests or connections is has, so depending on the work load and the resources of the machine, you may run into TCP issues. You can use Stream::buffered
to control how many futures are pending at a time.
WARNING: I am new to Rust and hyper
hello,
I want to figure out how to optimize performance of concurrent requests with hyper so that a machine can saturate its network link, the example below will get bottle necked by TCP port exhaustion, which would be solved by assigning an IPv4/6 range to the machine and use set_local_address, but see these two issues https://github.com/hyperium/hyper/issues/1684 https://github.com/hyperium/hyper/issues/1683 for why I have not implemented it yet. For IPv6, I can get a range from Hurricane Electric for free, to work around TCP port exhaustion.
HTTP2 could be used to work around TCP port exhaustion, but not all web servers support it.
Another common use case for this kind of optimization is a web spider.
consider this sample project Note that this project does not do concurrent requests for fetching book pages all at once, because the total number of pages is not known, guessing number of pages with HEAD requests to then fetch all pages in parallel will be faster and is more likely to bottle neck with TCP port exhaustion.
src/main.rs
Cargo.toml
PS: This project would make a good usage example for hyper