rama_http::layer::retry

Trait Policy

Source
pub trait Policy<S, R, E>:
    Send
    + Sync
    + 'static {
    // Required methods
    fn retry(
        &self,
        ctx: Context<S>,
        req: Request<RetryBody>,
        result: Result<R, E>,
    ) -> impl Future<Output = PolicyResult<S, R, E>> + Send + '_;
    fn clone_input(
        &self,
        ctx: &Context<S>,
        req: &Request<RetryBody>,
    ) -> Option<(Context<S>, Request<RetryBody>)>;
}
Expand description

A “retry policy” to classify if a request should be retried.

§Example

use rama_core::Context;
use rama_http::Request;
use rama_http::layer::retry::{Policy, PolicyResult, RetryBody};
use std::sync::Arc;
use parking_lot::Mutex;

struct Attempts(Arc<Mutex<usize>>);

impl<S, R, E> Policy<S, R, E> for Attempts
    where
        S: Clone + Send + Sync + 'static,
        R: Send + 'static,
        E: Send + Sync + 'static,
{
    async fn retry(&self, ctx: Context<S>, req: Request<RetryBody>, result: Result<R, E>) -> PolicyResult<S, R, E> {
        match result {
            Ok(_) => {
                // Treat all `Response`s as success,
                // so don't retry...
                PolicyResult::Abort(result)
            },
            Err(_) => {
                // Treat all errors as failures...
                // But we limit the number of attempts...
                let mut attempts = self.0.lock();
                if *attempts > 0 {
                    // Try again!
                    *attempts -= 1;
                    PolicyResult::Retry { ctx, req }
                } else {
                    // Used all our attempts, no retry...
                    PolicyResult::Abort(result)
                }
            }
        }
    }

    fn clone_input(&self, ctx: &Context<S>, req: &Request<RetryBody>) -> Option<(Context<S>, Request<RetryBody>)> {
        Some((ctx.clone(), req.clone()))
    }
}

Required Methods§

Source

fn retry( &self, ctx: Context<S>, req: Request<RetryBody>, result: Result<R, E>, ) -> impl Future<Output = PolicyResult<S, R, E>> + Send + '_

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 that will delay the next retry of the request. This can be used to sleep for a certain duration, to wait for some external condition to be met before retrying, or resolve right away, if the request should be retried immediately.

§Mutating Requests

The policy MAY chose to mutate the req: if the request is mutated, the mutated request will be sent to the inner service in the next retry. This can be helpful for use cases like tracking the retry count in a header.

§Mutating Results

The policy MAY chose to mutate the result. This enables the retry policy to convert a failure into a success and vice versa. For example, if the policy is used to poll while waiting for a state change, the policy can switch the result to emit a specific error when retries are exhausted.

The policy can also record metadata on the request to include information about the number of retries required or to record that a failure failed after exhausting all retries.

Source

fn clone_input( &self, ctx: &Context<S>, req: &Request<RetryBody>, ) -> Option<(Context<S>, Request<RetryBody>)>

Tries to clone a request before being passed to the inner service.

If the request cannot be cloned, return None. Moreover, the retry function will not be called if the None is returned.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<A, B, C, D, E, F, G, H, I, State, Response, Error> Policy<State, Response, Error> for Either9<A, B, C, D, E, F, G, H, I>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, D: Policy<State, Response, Error>, E: Policy<State, Response, Error>, F: Policy<State, Response, Error>, G: Policy<State, Response, Error>, H: Policy<State, Response, Error>, I: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, C, D, E, F, G, H, State, Response, Error> Policy<State, Response, Error> for Either8<A, B, C, D, E, F, G, H>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, D: Policy<State, Response, Error>, E: Policy<State, Response, Error>, F: Policy<State, Response, Error>, G: Policy<State, Response, Error>, H: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, C, D, E, F, G, State, Response, Error> Policy<State, Response, Error> for Either7<A, B, C, D, E, F, G>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, D: Policy<State, Response, Error>, E: Policy<State, Response, Error>, F: Policy<State, Response, Error>, G: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, C, D, E, F, State, Response, Error> Policy<State, Response, Error> for Either6<A, B, C, D, E, F>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, D: Policy<State, Response, Error>, E: Policy<State, Response, Error>, F: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, C, D, E, State, Response, Error> Policy<State, Response, Error> for Either5<A, B, C, D, E>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, D: Policy<State, Response, Error>, E: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, C, D, State, Response, Error> Policy<State, Response, Error> for Either4<A, B, C, D>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, D: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, C, State, Response, Error> Policy<State, Response, Error> for Either3<A, B, C>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, C: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<A, B, State, Response, Error> Policy<State, Response, Error> for Either<A, B>
where A: Policy<State, Response, Error>, B: Policy<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,

Source§

async fn retry( &self, ctx: Context<State>, req: Request<RetryBody>, result: Result<Response, Error>, ) -> PolicyResult<State, Response, Error>

Source§

fn clone_input( &self, ctx: &Context<State>, req: &Request<RetryBody>, ) -> Option<(Context<State>, Request<RetryBody>)>

Source§

impl<P, S, R, E> Policy<S, R, E> for &'static P
where P: Policy<S, R, E>,

Source§

fn retry( &self, ctx: Context<S>, req: Request<RetryBody>, result: Result<R, E>, ) -> impl Future<Output = PolicyResult<S, R, E>> + Send + '_

Source§

fn clone_input( &self, ctx: &Context<S>, req: &Request<RetryBody>, ) -> Option<(Context<S>, Request<RetryBody>)>

Source§

impl<P, S, R, E> Policy<S, R, E> for Arc<P>
where P: Policy<S, R, E>,

Source§

fn retry( &self, ctx: Context<S>, req: Request<RetryBody>, result: Result<R, E>, ) -> impl Future<Output = PolicyResult<S, R, E>> + Send + '_

Source§

fn clone_input( &self, ctx: &Context<S>, req: &Request<RetryBody>, ) -> Option<(Context<S>, Request<RetryBody>)>

Implementors§

Source§

impl<B, C, R, State, Response, Error> Policy<State, Response, Error> for ManagedPolicy<B, C, R>
where B: Backoff, C: CloneInput<State>, R: RetryRule<State, Response, Error>, State: Clone + Send + Sync + 'static, Response: Send + 'static, Error: Send + Sync + 'static,