//! Middleware that applies a timeout to requests. //! //! If the response does not complete within the specified timeout, the response //! will be aborted. pub mod error; pub mod future; mod layer; pub use self::layer::TimeoutLayer; use self::future::ResponseFuture; use std::task::{Context, Poll}; use std::time::Duration; use tower_service::Service; /// Applies a timeout to requests. #[derive(Debug, Clone)] pub struct Timeout { inner: T, timeout: Duration, } // ===== impl Timeout ===== impl Timeout { /// Creates a new [`Timeout`] pub fn new(inner: T, timeout: Duration) -> Self { Timeout { inner, timeout } } /// Get a reference to the inner service pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to the inner service pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Consume `self`, returning the inner service pub fn into_inner(self) -> T { self.inner } } impl Service for Timeout where S: Service, S::Error: Into, { type Response = S::Response; type Error = crate::BoxError; type Future = ResponseFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { match self.inner.poll_ready(cx) { Poll::Pending => Poll::Pending, Poll::Ready(r) => Poll::Ready(r.map_err(Into::into)), } } fn call(&mut self, request: Request) -> Self::Future { let response = self.inner.call(request); let sleep = tokio::time::sleep(self.timeout); ResponseFuture::new(response, sleep) } }