Add overall timeout for requests. (#67)
This deprecates timeout_read() and timeout_write() in favor of timeout(). The new timeout method on Request takes a Duration instead of a number of milliseconds, and is measured against overall request time, not per-read time. Once a request is started, the timeout is turned into a deadline specific to that call. The deadline is used in conjunction with the new DeadlineStream class, which sets a timeout on each read according to the remaining time for the request. Once the request is done, the DeadlineStream is unwrapped via .into::<Stream>() to become an undecorated Stream again for return to the pool. Timeouts on the stream are unset at this point. Still to be done: Add a setting on Agent for default timeout. Change header-writing code to apply overall deadline rather than per-write timeout. Fixes #28.
This commit is contained in:
committed by
GitHub
parent
d6b712f56f
commit
57be414d97
@@ -1,5 +1,6 @@
|
||||
use std::io::Read;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use qstring::QString;
|
||||
@@ -46,6 +47,7 @@ pub struct Request {
|
||||
pub(crate) timeout_connect: u64,
|
||||
pub(crate) timeout_read: u64,
|
||||
pub(crate) timeout_write: u64,
|
||||
pub(crate) timeout: Option<time::Duration>,
|
||||
pub(crate) redirects: u32,
|
||||
pub(crate) proxy: Option<crate::proxy::Proxy>,
|
||||
#[cfg(feature = "tls")]
|
||||
@@ -336,6 +338,8 @@ impl Request {
|
||||
}
|
||||
|
||||
/// Timeout for the socket connection to be successful.
|
||||
/// If both this and .timeout() are both set, .timeout_connect()
|
||||
/// takes precedence.
|
||||
///
|
||||
/// The default is `0`, which means a request can block forever.
|
||||
///
|
||||
@@ -351,6 +355,8 @@ impl Request {
|
||||
}
|
||||
|
||||
/// Timeout for the individual reads of the socket.
|
||||
/// If both this and .timeout() are both set, .timeout()
|
||||
/// takes precedence.
|
||||
///
|
||||
/// The default is `0`, which means it can block forever.
|
||||
///
|
||||
@@ -360,12 +366,15 @@ impl Request {
|
||||
/// .call();
|
||||
/// println!("{:?}", r);
|
||||
/// ```
|
||||
#[deprecated(note = "Please use the timeout() function instead")]
|
||||
pub fn timeout_read(&mut self, millis: u64) -> &mut Request {
|
||||
self.timeout_read = millis;
|
||||
self
|
||||
}
|
||||
|
||||
/// Timeout for the individual writes to the socket.
|
||||
/// If both this and .timeout() are both set, .timeout()
|
||||
/// takes precedence.
|
||||
///
|
||||
/// The default is `0`, which means it can block forever.
|
||||
///
|
||||
@@ -375,11 +384,32 @@ impl Request {
|
||||
/// .call();
|
||||
/// println!("{:?}", r);
|
||||
/// ```
|
||||
#[deprecated(note = "Please use the timeout() function instead")]
|
||||
pub fn timeout_write(&mut self, millis: u64) -> &mut Request {
|
||||
self.timeout_write = millis;
|
||||
self
|
||||
}
|
||||
|
||||
/// Timeout for the overall request, including DNS resolution, connection
|
||||
/// time, redirects, and reading the response body. Slow DNS resolution
|
||||
/// may cause a request to exceed the timeout, because the DNS request
|
||||
/// cannot be interrupted with the available APIs.
|
||||
///
|
||||
/// This takes precedence over .timeout_read() and .timeout_write(), but
|
||||
/// not .timeout_connect().
|
||||
///
|
||||
/// ```
|
||||
/// // wait max 1 second for whole request to complete.
|
||||
/// let r = ureq::get("/my_page")
|
||||
/// .timeout(std::time::Duration::from_secs(1))
|
||||
/// .call();
|
||||
/// println!("{:?}", r);
|
||||
/// ```
|
||||
pub fn timeout(&mut self, timeout: time::Duration) -> &mut Request {
|
||||
self.timeout = Some(timeout);
|
||||
self
|
||||
}
|
||||
|
||||
/// Basic auth.
|
||||
///
|
||||
/// These are the same
|
||||
|
||||
Reference in New Issue
Block a user