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