[][src]Struct tryhard::RetryFuture

pub struct RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT> { /* fields omitted */ }

A retryable future.

Can be created by calling retry_fn.

Implementations

impl<MakeFutureT, FutureT, BackoffT, T, E, OnRetryT> RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT> where
    MakeFutureT: FnMut() -> FutureT,
    FutureT: Future<Output = Result<T, E>>, 
[src]

pub fn max_delay(self, delay: Duration) -> Self[src]

Set the max duration to sleep between each attempt.

pub fn no_backoff(
    self
) -> RetryFuture<MakeFutureT, FutureT, NoBackoff, OnRetryT>

Notable traits for RetryFuture<F, Fut, B, OnRetryT>

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
type Output = Result<T, E>;
[src]

Remove the backoff strategy.

This will make the future be retried immediately without any delay in between attempts.

pub fn exponential_backoff(
    self,
    initial_delay: Duration
) -> RetryFuture<MakeFutureT, FutureT, ExponentialBackoff, OnRetryT>

Notable traits for RetryFuture<F, Fut, B, OnRetryT>

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
type Output = Result<T, E>;
[src]

Use exponential backoff for retrying the future.

The first delay will be initial_delay and afterwards the delay will double every time.

pub fn fixed_backoff(
    self,
    delay: Duration
) -> RetryFuture<MakeFutureT, FutureT, FixedBackoff, OnRetryT>

Notable traits for RetryFuture<F, Fut, B, OnRetryT>

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
type Output = Result<T, E>;
[src]

Use a fixed backoff for retrying the future.

The delay between attempts will always be delay.

pub fn linear_backoff(
    self,
    delay: Duration
) -> RetryFuture<MakeFutureT, FutureT, LinearBackoff, OnRetryT>

Notable traits for RetryFuture<F, Fut, B, OnRetryT>

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
type Output = Result<T, E>;
[src]

Use a linear backoff for retrying the future.

The delay will be delay * attempt so it'll scale linear with the attempt.

pub fn custom_backoff<F, R>(
    self,
    f: F
) -> RetryFuture<MakeFutureT, FutureT, CustomBackoffStrategy<F>, OnRetryT>

Notable traits for RetryFuture<F, Fut, B, OnRetryT>

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
type Output = Result<T, E>;
where
    F: FnMut(u32, &E) -> R,
    RetryPolicy: From<R>, 
[src]

Use a custom backoff specified by some function.

use std::time::Duration;

tryhard::retry_fn(|| read_file("Cargo.toml"))
    .retries(10)
    .custom_backoff(|attempt, _error| {
        if attempt < 5 {
            Duration::from_millis(100)
        } else {
            Duration::from_millis(500)
        }
    })
    .await?;

You can also stop retrying early:

use std::time::Duration;
use tryhard::RetryPolicy;

tryhard::retry_fn(|| read_file("Cargo.toml"))
    .retries(10)
    .custom_backoff(|attempt, error| {
        if error.to_string().contains("foobar") {
            // returning this will cancel the loop and
            // return the most recent error
            RetryPolicy::Break
        } else {
            RetryPolicy::Delay(Duration::from_millis(50))
        }
    })
    .await?;

pub fn on_retry<F, OnRetryFuture>(
    self,
    f: F
) -> RetryFuture<MakeFutureT, FutureT, BackoffT, F>

Notable traits for RetryFuture<F, Fut, B, OnRetryT>

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
type Output = Result<T, E>;
where
    F: FnMut(u32, Option<Duration>, &E) -> OnRetryFuture,
    OnRetryFuture: Future + Send + 'static,
    OnRetryFuture::Output: Send + 'static, 
[src]

Some async computation that will be spawned before each retry.

This can for example be used for telemtry such as logging or other kinds of tracking.

The future returned will be given to tokio::spawn so wont impact the actual retrying.

Example

For example to print and gather all the errors you can do:

use std::sync::Arc;
#[cfg(feature = "tokio-03")]
use tokio_03 as tokio;
#[cfg(feature = "tokio-02")]
use tokio_02 as tokio;
use tokio::sync::Mutex;

let all_errors = Arc::new(Mutex::new(Vec::new()));

tryhard::retry_fn(|| async {
    // just some dummy computation that always fails
    Err::<(), _>("fail")
})
    .retries(10)
    .on_retry(|_attempt, _next_delay, error| {
        // the future must be `'static` so it cannot contain references
        let all_errors = Arc::clone(&all_errors);
        let error = error.clone();
        async move {
            eprintln!("Something failed: {}", error);
            all_errors.lock().await.push(error);
        }
    })
    .await
    .unwrap_err();

assert_eq!(all_errors.lock().await.len(), 10);

Trait Implementations

impl<F, Fut, B, T, E, OnRetryT> Future for RetryFuture<F, Fut, B, OnRetryT> where
    F: FnMut() -> Fut,
    Fut: Future<Output = Result<T, E>>,
    E: Display,
    B: BackoffStrategy<E>,
    RetryPolicy: From<B::Output>,
    OnRetryT: OnRetry<E>, 
[src]

type Output = Result<T, E>

The type of value produced on completion.

impl<'pin, MakeFutureT, FutureT, BackoffT, OnRetryT> Unpin for RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT> where
    __RetryFuture<'pin, MakeFutureT, FutureT, BackoffT, OnRetryT>: Unpin
[src]

Auto Trait Implementations

impl<MakeFutureT, FutureT, BackoffT, OnRetryT> !RefUnwindSafe for RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT>

impl<MakeFutureT, FutureT, BackoffT, OnRetryT> Send for RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT> where
    BackoffT: Send,
    FutureT: Send,
    MakeFutureT: Send,
    OnRetryT: Send

impl<MakeFutureT, FutureT, BackoffT, OnRetryT> Sync for RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT> where
    BackoffT: Sync,
    FutureT: Sync,
    MakeFutureT: Sync,
    OnRetryT: Sync

impl<MakeFutureT, FutureT, BackoffT, OnRetryT> !UnwindSafe for RetryFuture<MakeFutureT, FutureT, BackoffT, OnRetryT>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> FutureExt for T where
    T: Future + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<F> IntoFuture for F where
    F: Future
[src]

type Output = <F as Future>::Output

🔬 This is a nightly-only experimental API. (into_future)

The output that the future will produce on completion.

type Future = F

🔬 This is a nightly-only experimental API. (into_future)

Which kind of future are we turning this into?

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<F, T, E> TryFuture for F where
    F: Future<Output = Result<T, E>> + ?Sized
[src]

type Ok = T

The type of successful values yielded by this future

type Error = E

The type of failures yielded by this future

impl<Fut> TryFutureExt for Fut where
    Fut: TryFuture + ?Sized
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.