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