How to set timeout for HTTP request with hyper, tokio and futures in Rust?

Viewed 4212

How do I set a timeout for HTTP request using asynchronous Hyper (>= 0.11)?

Here is the example of the code without timeout:

extern crate hyper;
extern crate tokio_core;
extern crate futures;

use futures::Future;
use hyper::Client;
use tokio_core::reactor::Core;

fn main() {
    let mut core = Core::new().unwrap();
    let client = Client::new(&core.handle());

    let uri = "http://stackoverflow.com".parse().unwrap();
    let work = client.get(uri).map(|res| {
        res.status()
    });

    match core.run(work) {
        Ok(status) => println!("Status: {}", status),
        Err(e) => println!("Error: {:?}", e)
    }
}
2 Answers

Just FYI this has gotten a lot easier with Tokyo >= 1.0, because they now have a dedicated timeout wrapper that can be applied to a future (such as a request) and which wraps the original future type inside a Result whose Ok is the original future type and whose Err is a timeout error.

Thus your code in the question can now handle timeouts as follows:

extern crate tokio; // 1.7.1, full features

use hyper::Client;
use std::time::Duration;

#[tokio::main]
async fn main() {
    let client = Client::new();


    let uri = "http://stackoverflow.com".parse().unwrap();
    let work = client.get(uri);

    match tokio::time::timeout(Duration::from_millis(10), work).await {
        Ok(result) => match result {
            Ok(response) => println!("Status: {}", response.status()),
            Err(e) => println!("Network error: {:?}", e),
        },
        Err(_) => println!("Timeout: no response in 10 milliseconds."),
    };
}

(Of course, this code will always give you a timeout. To see the expected 301 response from the network, try going to 200 milliseconds.)

Related