Hyper: Request timeouts

Created on 19 Mar 2017  ·  5Comments  ·  Source: hyperium/hyper

Is it possible to configure request or HTTP client timeouts?
I am interested in master/tokio branch.

Most helpful comment

As of now, there isn't specific timeouts to set that are inside hyper. There are a few reasons why, but the main reason was because using futures makes it quite simple for anyone to deal with timeouts external to hyper. For example:

let timeout = tokio_core::reactor::Timeout::new(Duration:from_secs(30), &handle))?;
// a tokio timeout doesn't necessarily mean an error,
//  but in our case, always make it an error
// (it could also be used for things like "send this message after this amount of time")
let timeout = timeout.then(|_| Err(io::Error::new(io::ErrorKind::TimedOut, "our timeout")));
// set up our client request
let future_body = client.get(some_url).and_then(|res| {
    res.body().fold(Vec::new(), |mut vec, chunk| {
        vec.extend_from_slice(&chunk);
        Ok(vec)
    })
});

// select on the request and the timeout
// the first one to 'complete' will trigger our callback
// since we converted the timeout to always be an error,
// it will only ever be in the `Err` variant
let work = future_body.select(timeout).then(|result| {
    match result { 
        Ok(body) => {
            // do something with the body
        },
        Err(e) => {
            // could be an http  or io error (including our time out error)
            // inspect to find out which it was
        }
    }
});
handle.spawn(work);

All 5 comments

As of now, there isn't specific timeouts to set that are inside hyper. There are a few reasons why, but the main reason was because using futures makes it quite simple for anyone to deal with timeouts external to hyper. For example:

let timeout = tokio_core::reactor::Timeout::new(Duration:from_secs(30), &handle))?;
// a tokio timeout doesn't necessarily mean an error,
//  but in our case, always make it an error
// (it could also be used for things like "send this message after this amount of time")
let timeout = timeout.then(|_| Err(io::Error::new(io::ErrorKind::TimedOut, "our timeout")));
// set up our client request
let future_body = client.get(some_url).and_then(|res| {
    res.body().fold(Vec::new(), |mut vec, chunk| {
        vec.extend_from_slice(&chunk);
        Ok(vec)
    })
});

// select on the request and the timeout
// the first one to 'complete' will trigger our callback
// since we converted the timeout to always be an error,
// it will only ever be in the `Err` variant
let work = future_body.select(timeout).then(|result| {
    match result { 
        Ok(body) => {
            // do something with the body
        },
        Err(e) => {
            // could be an http  or io error (including our time out error)
            // inspect to find out which it was
        }
    }
});
handle.spawn(work);

Thanks, that explains a lot.
I can't see any correlation between timeouts and request, how can I ensure that request is cancelled after timeout?

If the request future is dropped, then that can trigger a cancellation. The
example with select above will drop the request future if the timeout
competes first. That is how the request is cancelled.
On Sun, Mar 19, 2017 at 10:55 AM Łukasz Kurowski notifications@github.com
wrote:

Thanks, that explains a lot.
I can't see any correlation between timeouts and request, how can I ensure
that request is cancelled after timeout?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/hyperium/hyper/issues/1097#issuecomment-287634290,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAYJALkjAv9KTabGbGlLPWdx8nj6mgxks5rnWwTgaJpZM4MhxZh
.

@carllerche this is a great mechanism, thank you for this explanation and @seanmonstar thank you for this example.

As of now, there isn't specific timeouts to set that are inside hyper. There are a few reasons why, but the main reason was because using futures makes it quite simple for anyone to deal with timeouts external to hyper. For example:

let timeout = tokio_core::reactor::Timeout::new(Duration:from_secs(30), &handle))?;
// a tokio timeout doesn't necessarily mean an error,
//  but in our case, always make it an error
// (it could also be used for things like "send this message after this amount of time")
let timeout = timeout.then(|_| Err(io::Error::new(io::ErrorKind::TimedOut, "our timeout")));
// set up our client request
let future_body = client.get(some_url).and_then(|res| {
    res.body().fold(Vec::new(), |mut vec, chunk| {
        vec.extend_from_slice(&chunk);
        Ok(vec)
    })
});

// select on the request and the timeout
// the first one to 'complete' will trigger our callback
// since we converted the timeout to always be an error,
// it will only ever be in the `Err` variant
let work = future_body.select(timeout).then(|result| {
    match result { 
        Ok(body) => {
            // do something with the body
        },
        Err(e) => {
            // could be an http  or io error (including our time out error)
            // inspect to find out which it was
        }
    }
});
handle.spawn(work);

Hello, I found your code have compile error.
let work = future_body.select(timeout).then(|result| {
| ^^^^^^ expected struct std::io::Error, found struct hyper::Error

Was this page helpful?
0 / 5 - 0 ratings

Related issues

toplinuxsir picture toplinuxsir  ·  3Comments

FGRibreau picture FGRibreau  ·  4Comments

Visic picture Visic  ·  4Comments

fabioberger picture fabioberger  ·  5Comments

Firstyear picture Firstyear  ·  4Comments