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