1pub mod budget;
4mod layer;
5mod policy;
6
7pub use self::layer::RetryLayer;
8pub use self::policy::Policy;
9
10use tower_async_service::Service;
11
12#[derive(Clone, Debug)]
16pub struct Retry<P, S> {
17 policy: P,
18 service: S,
19}
20
21impl<P, S> Retry<P, S> {
24 pub fn new(policy: P, service: S) -> Self {
26 Retry { policy, service }
27 }
28
29 pub fn get_ref(&self) -> &S {
31 &self.service
32 }
33
34 pub fn into_inner(self) -> S {
36 self.service
37 }
38}
39
40impl<P, S, Request> Service<Request> for Retry<P, S>
41where
42 P: Policy<Request, S::Response, S::Error>,
43 S: Service<Request>,
44{
45 type Response = S::Response;
46 type Error = S::Error;
47
48 async fn call(&self, mut request: Request) -> Result<Self::Response, Self::Error> {
49 loop {
50 let cloned_request = self.policy.clone_request(&request);
51 let mut result = self.service.call(request).await;
52 if let Some(mut req) = cloned_request {
53 if !self.policy.retry(&mut req, &mut result).await {
54 return result;
55 }
56 request = req;
57 } else {
58 return result;
59 }
60 }
61 }
62}