1 //! Tower middleware that applies a timeout to requests.
2 //!
3 //! If the response does not complete within the specified timeout, the response
4 //! will be aborted.
5 
6 pub mod error;
7 pub mod future;
8 mod layer;
9 
10 pub use self::layer::TimeoutLayer;
11 
12 use self::{error::Error, future::ResponseFuture};
13 use std::task::{Context, Poll};
14 use std::time::Duration;
15 use tower_service::Service;
16 
17 /// Applies a timeout to requests.
18 #[derive(Debug, Clone)]
19 pub struct Timeout<T> {
20     inner: T,
21     timeout: Duration,
22 }
23 
24 // ===== impl Timeout =====
25 
26 impl<T> Timeout<T> {
27     /// Creates a new Timeout
new(inner: T, timeout: Duration) -> Self28     pub fn new(inner: T, timeout: Duration) -> Self {
29         Timeout { inner, timeout }
30     }
31 }
32 
33 impl<S, Request> Service<Request> for Timeout<S>
34 where
35     S: Service<Request>,
36     S::Error: Into<Error>,
37 {
38     type Response = S::Response;
39     type Error = Error;
40     type Future = ResponseFuture<S::Future>;
41 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>42     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
43         match self.inner.poll_ready(cx) {
44             Poll::Pending => Poll::Pending,
45             Poll::Ready(r) => Poll::Ready(r.map_err(Into::into)),
46         }
47     }
48 
call(&mut self, request: Request) -> Self::Future49     fn call(&mut self, request: Request) -> Self::Future {
50         let response = self.inner.call(request);
51         let sleep = tokio::time::delay_for(self.timeout);
52 
53         ResponseFuture::new(response, sleep)
54     }
55 }
56