diff --git a/tower/src/retry/future.rs b/tower/src/retry/future.rs index d6988ec30..95e2c3af3 100644 --- a/tower/src/retry/future.rs +++ b/tower/src/retry/future.rs @@ -1,6 +1,7 @@ //! Future types -use super::{Policy, Retry}; +use super::Retry; +use crate::retry::PolicyV2; use futures_core::ready; use pin_project::pin_project; use std::future::Future; @@ -13,7 +14,7 @@ use tower_service::Service; #[derive(Debug)] pub struct ResponseFuture where - P: Policy, + P: PolicyV2, S: Service, { request: Option, @@ -36,7 +37,7 @@ enum State { impl ResponseFuture where - P: Policy, + P: PolicyV2, S: Service, { pub(crate) fn new( @@ -54,7 +55,7 @@ where impl Future for ResponseFuture where - P: Policy + Clone, + P: PolicyV2 + Clone, S: Service + Clone, { type Output = Result; @@ -67,11 +68,11 @@ where StateProj::Called(future) => { let result = ready!(future.poll(cx)); if let Some(ref req) = this.request { - match this.retry.policy.retry(req, result.as_ref()) { - Some(checking) => { + match this.retry.policy.retry(req, result) { + Err(checking) => { this.state.set(State::Checking(checking)); } - None => return Poll::Ready(result), + Ok(result) => return Poll::Ready(result), } } else { // request wasn't cloned, so no way to retry it diff --git a/tower/src/retry/mod.rs b/tower/src/retry/mod.rs index 98fb084e9..eacd439a0 100644 --- a/tower/src/retry/mod.rs +++ b/tower/src/retry/mod.rs @@ -4,9 +4,11 @@ pub mod budget; pub mod future; mod layer; mod policy; +mod policyv2; pub use self::layer::RetryLayer; pub use self::policy::Policy; +pub use self::policyv2::PolicyV2; use self::future::ResponseFuture; use pin_project::pin_project; @@ -50,7 +52,7 @@ impl Retry { impl Service for Retry where - P: Policy + Clone, + P: PolicyV2 + Clone, S: Service + Clone, { type Response = S::Response; diff --git a/tower/src/retry/policyv2.rs b/tower/src/retry/policyv2.rs new file mode 100644 index 000000000..b28f35060 --- /dev/null +++ b/tower/src/retry/policyv2.rs @@ -0,0 +1,45 @@ +use crate::retry::Policy; +use std::future::Future; + +/// TODO docs +pub trait PolicyV2: Sized { + /// The [`Future`] type returned by [`Policy::retry`]. + type Future: Future; + + /// Check the policy if a certain request should be retried. + /// + /// This method is passed a reference to the original request, and either + /// the [`Service::Response`] or [`Service::Error`] from the inner service. + /// + /// If the request should **not** be retried, return `None`. + /// + /// If the request *should* be retried, return `Some` future of a new + /// policy that would apply for the next request attempt. + /// + /// [`Service::Response`]: crate::Service::Response + /// [`Service::Error`]: crate::Service::Error + fn retry(&self, req: &Req, result: Result) -> Result, Self::Future>; + + /// Tries to clone a request before being passed to the inner service. + /// + /// If the request cannot be cloned, return [`None`]. + fn clone_request(&self, req: &Req) -> Option; +} + +impl PolicyV2 for T +where + T: Policy, +{ + type Future = T::Future; + + fn retry(&self, req: &Req, result: Result) -> Result, Self::Future> { + match Policy::::retry(self, req, result.as_ref()) { + Some(fut) => Err(fut), + None => Ok(result), + } + } + + fn clone_request(&self, req: &Req) -> Option { + Policy::::clone_request(self, req) + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy