/rust/registry/src/index.crates.io-6f17d22bba15001f/tower-0.4.13/src/retry/mod.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Middleware for retrying "failed" requests. |
2 | | |
3 | | pub mod budget; |
4 | | pub mod future; |
5 | | mod layer; |
6 | | mod policy; |
7 | | |
8 | | pub use self::layer::RetryLayer; |
9 | | pub use self::policy::Policy; |
10 | | |
11 | | use self::future::ResponseFuture; |
12 | | use pin_project_lite::pin_project; |
13 | | use std::task::{Context, Poll}; |
14 | | use tower_service::Service; |
15 | | |
16 | | pin_project! { |
17 | | /// Configure retrying requests of "failed" responses. |
18 | | /// |
19 | | /// A [`Policy`] classifies what is a "failed" response. |
20 | | #[derive(Clone, Debug)] |
21 | | pub struct Retry<P, S> { |
22 | | #[pin] |
23 | | policy: P, |
24 | | service: S, |
25 | | } |
26 | | } |
27 | | |
28 | | // ===== impl Retry ===== |
29 | | |
30 | | impl<P, S> Retry<P, S> { |
31 | | /// Retry the inner service depending on this [`Policy`]. |
32 | 0 | pub fn new(policy: P, service: S) -> Self { |
33 | 0 | Retry { policy, service } |
34 | 0 | } |
35 | | |
36 | | /// Get a reference to the inner service |
37 | 0 | pub fn get_ref(&self) -> &S { |
38 | 0 | &self.service |
39 | 0 | } |
40 | | |
41 | | /// Get a mutable reference to the inner service |
42 | 0 | pub fn get_mut(&mut self) -> &mut S { |
43 | 0 | &mut self.service |
44 | 0 | } |
45 | | |
46 | | /// Consume `self`, returning the inner service |
47 | 0 | pub fn into_inner(self) -> S { |
48 | 0 | self.service |
49 | 0 | } |
50 | | } |
51 | | |
52 | | impl<P, S, Request> Service<Request> for Retry<P, S> |
53 | | where |
54 | | P: Policy<Request, S::Response, S::Error> + Clone, |
55 | | S: Service<Request> + Clone, |
56 | | { |
57 | | type Response = S::Response; |
58 | | type Error = S::Error; |
59 | | type Future = ResponseFuture<P, S, Request>; |
60 | | |
61 | 0 | fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { |
62 | 0 | // NOTE: the Future::poll impl for ResponseFuture assumes that Retry::poll_ready is |
63 | 0 | // equivalent to Ready.service.poll_ready. If this ever changes, that code must be updated |
64 | 0 | // as well. |
65 | 0 | self.service.poll_ready(cx) |
66 | 0 | } |
67 | | |
68 | 0 | fn call(&mut self, request: Request) -> Self::Future { |
69 | 0 | let cloned = self.policy.clone_request(&request); |
70 | 0 | let future = self.service.call(request); |
71 | 0 |
|
72 | 0 | ResponseFuture::new(cloned, self.clone(), future) |
73 | 0 | } |
74 | | } |