reqwest_retry

Struct RetryTransientMiddleware

Source
pub struct RetryTransientMiddleware<T: RetryPolicy + Send + Sync + 'static, R: RetryableStrategy + Send + Sync + 'static = DefaultRetryableStrategy> { /* private fields */ }
Expand description

RetryTransientMiddleware offers retry logic for requests that fail in a transient manner and can be safely executed again.

Currently, it allows setting a RetryPolicy algorithm for calculating the wait_time between each request retry. Sleeping on non-wasm32 archs is performed using tokio::time::sleep, therefore it will respect pauses/auto-advance if run under a runtime that supports them.

     use std::time::Duration;
     use reqwest_middleware::ClientBuilder;
     use retry_policies::{RetryDecision, RetryPolicy, Jitter};
     use retry_policies::policies::ExponentialBackoff;
     use reqwest_retry::RetryTransientMiddleware;
     use reqwest::Client;

     // We create a ExponentialBackoff retry policy which implements `RetryPolicy`.
     let retry_policy = ExponentialBackoff::builder()
         .retry_bounds(Duration::from_secs(1), Duration::from_secs(60))
         .jitter(Jitter::Bounded)
         .base(2)
         .build_with_total_retry_duration(Duration::from_secs(24 * 60 * 60));

     let retry_transient_middleware = RetryTransientMiddleware::new_with_policy(retry_policy);
     let client = ClientBuilder::new(Client::new()).with(retry_transient_middleware).build();

§Note

This middleware always errors when given requests with streaming bodies, before even executing the request. When this happens you’ll get an Error::Middleware with the message ‘Request object is not cloneable. Are you passing a streaming body?’.

Some workaround suggestions:

  • If you can fit the data in memory, you can instead build static request bodies e.g. with Body’s From<String> or From<Bytes> implementations.
  • You can wrap this middleware in a custom one which skips retries for streaming requests.
  • You can write a custom retry middleware that builds new streaming requests from the data source directly, avoiding the issue of streaming requests not being cloneable.

Implementations§

Source§

impl<T: RetryPolicy + Send + Sync> RetryTransientMiddleware<T, DefaultRetryableStrategy>

Source

pub fn new_with_policy(retry_policy: T) -> Self

Construct RetryTransientMiddleware with a retry_policy.

Source

pub fn with_retry_log_level(self, level: Level) -> Self

Set the log level for retry events. The default is WARN.

Source§

impl<T, R> RetryTransientMiddleware<T, R>

Source

pub fn new_with_policy_and_strategy( retry_policy: T, retryable_strategy: R, ) -> Self

Construct RetryTransientMiddleware with a retry_policy and retryable_strategy.

Trait Implementations§

Source§

impl<T, R> Middleware for RetryTransientMiddleware<T, R>
where T: RetryPolicy + Send + Sync, R: RetryableStrategy + Send + Sync + 'static,

Source§

fn handle<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, req: Request, extensions: &'life1 mut Extensions, next: Next<'life2>, ) -> Pin<Box<dyn Future<Output = Result<Response>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Invoked with a request before sending it. If you want to continue processing the request, you should explicitly call next.run(req, extensions). Read more

Auto Trait Implementations§

§

impl<T, R> Freeze for RetryTransientMiddleware<T, R>
where T: Freeze, R: Freeze,

§

impl<T, R> RefUnwindSafe for RetryTransientMiddleware<T, R>

§

impl<T, R> Send for RetryTransientMiddleware<T, R>

§

impl<T, R> Sync for RetryTransientMiddleware<T, R>

§

impl<T, R> Unpin for RetryTransientMiddleware<T, R>
where T: Unpin, R: Unpin,

§

impl<T, R> UnwindSafe for RetryTransientMiddleware<T, R>
where T: UnwindSafe, R: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T