Coverage Report

Created: 2026-01-30 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.5.2/src/retry/mod.rs
Line
Count
Source
1
//! Middleware for retrying "failed" requests.
2
3
pub mod backoff;
4
pub mod budget;
5
pub mod future;
6
mod layer;
7
mod policy;
8
9
pub use self::layer::RetryLayer;
10
pub use self::policy::Policy;
11
12
use self::future::ResponseFuture;
13
use pin_project_lite::pin_project;
14
use std::task::{Context, Poll};
15
use tower_service::Service;
16
17
pin_project! {
18
    /// Configure retrying requests of "failed" responses.
19
    ///
20
    /// A [`Policy`] classifies what is a "failed" response.
21
    ///
22
    /// # Clone
23
    ///
24
    /// This middleware requires that the inner `Service` implements [`Clone`],
25
    /// because the `Service` must be stored in each [`ResponseFuture`] in
26
    /// order to retry the request in the event of a failure. If the inner
27
    /// `Service` type does not implement `Clone`, the [`Buffer`] middleware
28
    /// can be added to make any `Service` cloneable.
29
    ///
30
    /// [`Buffer`]: crate::buffer::Buffer
31
    ///
32
    /// The `Policy` must also implement `Clone`. This middleware will
33
    /// clone the policy for each _request session_. This means a new clone
34
    /// of the policy will be created for each initial request and any subsequent
35
    /// retries of that request. Therefore, any state stored in the `Policy` instance
36
    /// is for that request session only. In order to share data across request
37
    /// sessions, that shared state may be stored in an [`Arc`], so that all clones
38
    /// of the `Policy` type reference the same instance of the shared state.
39
    ///
40
    /// [`Arc`]: std::sync::Arc
41
    #[derive(Clone, Debug)]
42
    pub struct Retry<P, S> {
43
        policy: P,
44
        service: S,
45
    }
46
}
47
48
// ===== impl Retry =====
49
50
impl<P, S> Retry<P, S> {
51
    /// Retry the inner service depending on this [`Policy`].
52
0
    pub const fn new(policy: P, service: S) -> Self {
53
0
        Retry { policy, service }
54
0
    }
Unexecuted instantiation: <tower::retry::Retry<reqwest::retry::Policy, reqwest::async_impl::client::HyperService>>::new
Unexecuted instantiation: <tower::retry::Retry<_, _>>::new
55
56
    /// Get a reference to the inner service
57
0
    pub fn get_ref(&self) -> &S {
58
0
        &self.service
59
0
    }
60
61
    /// Get a mutable reference to the inner service
62
0
    pub fn get_mut(&mut self) -> &mut S {
63
0
        &mut self.service
64
0
    }
65
66
    /// Consume `self`, returning the inner service
67
0
    pub fn into_inner(self) -> S {
68
0
        self.service
69
0
    }
70
}
71
72
impl<P, S, Request> Service<Request> for Retry<P, S>
73
where
74
    P: Policy<Request, S::Response, S::Error> + Clone,
75
    S: Service<Request> + Clone,
76
{
77
    type Response = S::Response;
78
    type Error = S::Error;
79
    type Future = ResponseFuture<P, S, Request>;
80
81
0
    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
82
        // NOTE: the Future::poll impl for ResponseFuture assumes that Retry::poll_ready is
83
        // equivalent to Ready.service.poll_ready. If this ever changes, that code must be updated
84
        // as well.
85
0
        self.service.poll_ready(cx)
86
0
    }
Unexecuted instantiation: <tower::retry::Retry<reqwest::retry::Policy, reqwest::async_impl::client::HyperService> as tower_service::Service<http::request::Request<reqwest::async_impl::body::Body>>>::poll_ready
Unexecuted instantiation: <tower::retry::Retry<_, _> as tower_service::Service<_>>::poll_ready
87
88
0
    fn call(&mut self, request: Request) -> Self::Future {
89
0
        let cloned = self.policy.clone_request(&request);
90
0
        let future = self.service.call(request);
91
92
0
        ResponseFuture::new(cloned, self.clone(), future)
93
0
    }
Unexecuted instantiation: <tower::retry::Retry<reqwest::retry::Policy, reqwest::async_impl::client::HyperService> as tower_service::Service<http::request::Request<reqwest::async_impl::body::Body>>>::call
Unexecuted instantiation: <tower::retry::Retry<_, _> as tower_service::Service<_>>::call
94
}