1 #![doc(html_root_url = "https://docs.rs/tower-timeout/0.1.1")]
2 #![deny(missing_debug_implementations, missing_docs, rust_2018_idioms)]
3 #![allow(elided_lifetimes_in_paths)]
4 #![cfg_attr(test, deny(warnings))]
5 
6 //! Tower middleware that applies a timeout to requests.
7 //!
8 //! If the response does not complete within the specified timeout, the response
9 //! will be aborted.
10 
11 pub mod error;
12 pub mod future;
13 mod layer;
14 
15 pub use crate::layer::TimeoutLayer;
16 
17 use crate::{error::Error, future::ResponseFuture};
18 use futures::Poll;
19 use tokio_timer::{clock, Delay};
20 
21 use tower_service::Service;
22 
23 use std::time::Duration;
24 
25 /// Applies a timeout to requests.
26 #[derive(Debug, Clone)]
27 pub struct Timeout<T> {
28     inner: T,
29     timeout: Duration,
30 }
31 
32 // ===== impl Timeout =====
33 
34 impl<T> Timeout<T> {
35     /// Creates a new Timeout
new(inner: T, timeout: Duration) -> Self36     pub fn new(inner: T, timeout: Duration) -> Self {
37         Timeout { inner, timeout }
38     }
39 }
40 
41 impl<S, Request> Service<Request> for Timeout<S>
42 where
43     S: Service<Request>,
44     Error: From<S::Error>,
45 {
46     type Response = S::Response;
47     type Error = Error;
48     type Future = ResponseFuture<S::Future>;
49 
poll_ready(&mut self) -> Poll<(), Self::Error>50     fn poll_ready(&mut self) -> Poll<(), Self::Error> {
51         self.inner.poll_ready().map_err(Into::into)
52     }
53 
call(&mut self, request: Request) -> Self::Future54     fn call(&mut self, request: Request) -> Self::Future {
55         let response = self.inner.call(request);
56         let sleep = Delay::new(clock::now() + self.timeout);
57 
58         ResponseFuture::new(response, sleep)
59     }
60 }
61