tower_async/timeout/
mod.rs

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
6pub mod error;
7mod layer;
8
9pub use self::layer::TimeoutLayer;
10
11use error::Elapsed;
12
13use std::time::Duration;
14use tower_async_service::Service;
15
16/// Applies a timeout to requests.
17#[derive(Debug, Clone)]
18pub struct Timeout<T> {
19    inner: T,
20    timeout: Duration,
21}
22
23// ===== impl Timeout =====
24
25impl<T> Timeout<T> {
26    /// Creates a new [`Timeout`]
27    pub fn new(inner: T, timeout: Duration) -> Self {
28        Timeout { inner, timeout }
29    }
30
31    /// Get a reference to the inner service
32    pub fn get_ref(&self) -> &T {
33        &self.inner
34    }
35
36    /// Consume `self`, returning the inner service
37    pub fn into_inner(self) -> T {
38        self.inner
39    }
40}
41
42impl<S, Request> Service<Request> for Timeout<S>
43where
44    S: Service<Request>,
45    S::Error: Into<crate::BoxError>,
46{
47    type Response = S::Response;
48    type Error = crate::BoxError;
49
50    async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
51        tokio::select! {
52            res = self.inner.call(request) => res.map_err(Into::into),
53            _ = tokio::time::sleep(self.timeout) => Err(Elapsed(()).into()),
54        }
55    }
56}