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
’sFrom<String>
orFrom<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>
impl<T: RetryPolicy + Send + Sync> RetryTransientMiddleware<T, DefaultRetryableStrategy>
Sourcepub fn new_with_policy(retry_policy: T) -> Self
pub fn new_with_policy(retry_policy: T) -> Self
Construct RetryTransientMiddleware
with a retry_policy.
Sourcepub fn with_retry_log_level(self, level: Level) -> Self
pub fn with_retry_log_level(self, level: Level) -> Self
Source§impl<T, R> RetryTransientMiddleware<T, R>
impl<T, R> RetryTransientMiddleware<T, R>
Sourcepub fn new_with_policy_and_strategy(
retry_policy: T,
retryable_strategy: R,
) -> Self
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>
impl<T, R> Middleware for RetryTransientMiddleware<T, R>
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,
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,
next.run(req, extensions)
. Read more