1 use std::future::Future; 2 3 /// A "retry policy" to classify if a request should be retried. 4 /// 5 /// # Example 6 /// 7 /// ``` 8 /// use tower::retry::Policy; 9 /// use futures_util::future; 10 /// 11 /// type Req = String; 12 /// type Res = String; 13 /// 14 /// struct Attempts(usize); 15 /// 16 /// impl<E> Policy<Req, Res, E> for Attempts { 17 /// type Future = future::Ready<Self>; 18 /// 19 /// fn retry(&self, req: &Req, result: Result<&Res, &E>) -> Option<Self::Future> { 20 /// match result { 21 /// Ok(_) => { 22 /// // Treat all `Response`s as success, 23 /// // so don't retry... 24 /// None 25 /// }, 26 /// Err(_) => { 27 /// // Treat all errors as failures... 28 /// // But we limit the number of attempts... 29 /// if self.0 > 0 { 30 /// // Try again! 31 /// Some(future::ready(Attempts(self.0 - 1))) 32 /// } else { 33 /// // Used all our attempts, no retry... 34 /// None 35 /// } 36 /// } 37 /// } 38 /// } 39 /// 40 /// fn clone_request(&self, req: &Req) -> Option<Req> { 41 /// Some(req.clone()) 42 /// } 43 /// } 44 /// ``` 45 pub trait Policy<Req, Res, E>: Sized { 46 /// The [`Future`] type returned by [`Policy::retry`]. 47 type Future: Future<Output = Self>; 48 49 /// Check the policy if a certain request should be retried. 50 /// 51 /// This method is passed a reference to the original request, and either 52 /// the [`Service::Response`] or [`Service::Error`] from the inner service. 53 /// 54 /// If the request should **not** be retried, return `None`. 55 /// 56 /// If the request *should* be retried, return `Some` future of a new 57 /// policy that would apply for the next request attempt. 58 /// 59 /// [`Service::Response`]: crate::Service::Response 60 /// [`Service::Error`]: crate::Service::Error retry(&self, req: &Req, result: Result<&Res, &E>) -> Option<Self::Future>61 fn retry(&self, req: &Req, result: Result<&Res, &E>) -> Option<Self::Future>; 62 63 /// Tries to clone a request before being passed to the inner service. 64 /// 65 /// If the request cannot be cloned, return [`None`]. clone_request(&self, req: &Req) -> Option<Req>66 fn clone_request(&self, req: &Req) -> Option<Req>; 67 } 68