1 //! 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::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     /// Get a reference to the inner service
get_ref(&self) -> &T33     pub fn get_ref(&self) -> &T {
34         &self.inner
35     }
36 
37     /// Get a mutable reference to the inner service
get_mut(&mut self) -> &mut T38     pub fn get_mut(&mut self) -> &mut T {
39         &mut self.inner
40     }
41 
42     /// Consume `self`, returning the inner service
into_inner(self) -> T43     pub fn into_inner(self) -> T {
44         self.inner
45     }
46 }
47 
48 impl<S, Request> Service<Request> for Timeout<S>
49 where
50     S: Service<Request>,
51     S::Error: Into<crate::BoxError>,
52 {
53     type Response = S::Response;
54     type Error = crate::BoxError;
55     type Future = ResponseFuture<S::Future>;
56 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>57     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
58         match self.inner.poll_ready(cx) {
59             Poll::Pending => Poll::Pending,
60             Poll::Ready(r) => Poll::Ready(r.map_err(Into::into)),
61         }
62     }
63 
call(&mut self, request: Request) -> Self::Future64     fn call(&mut self, request: Request) -> Self::Future {
65         let response = self.inner.call(request);
66         let sleep = tokio::time::sleep(self.timeout);
67 
68         ResponseFuture::new(response, sleep)
69     }
70 }
71