pub async fn retry_or_first_error<B, T>(
    backoff: B,
    task: T
) -> Result<T::Ok, T::Error>
where B: Backoff<T::Error>, T: Task,
Expand description

Execute the async task. If it errs out, attempt to run the task again after a delay if the backoff yields a duration. Otherwise, return the first error that occurred to the caller.

§Examples

retry_or_first_error will succeed if the task returns Ok before the backoff returns None.

let counter = Arc::new(AtomicUsize::new(0));
let result = retry_or_first_error(
    repeat(Duration::from_secs(1)),
    || async {
        let count = counter.fetch_add(1, Ordering::SeqCst);
        if count == 5 {
            Ok(count)
        } else {
            Err(count)
        }
    }),
).await;
assert_eq!(result, Ok(5));

If the task fails, the retry_or_first_error will return the first error.

let counter = Arc::new(AtomicUsize::new(0));
let result = retry_or_first_error(
    repeat(Duration::from_secs(1)).take(5),
    || async {
        let count = counter.fetch_add(1, Ordering::SeqCst);
        Err(count)
    }),
).await;
assert_eq!(result, Err(0));