/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 | | } |