pub async fn retry_or_collect_errors<B, T, C>(
    backoff: B,
    task: T
) -> Result<T::Ok, C>
where B: Backoff<T::Error>, T: Task, C: Default + Extend<T::Error>,
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, collect all the errors and return them to the caller.

§Examples

retry_or_last_error will succeed if it returns Ok before the backoff returns None.

let counter = Arc::new(AtomicUsize::new(0));
let result = retry_or_collect_errors(
    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, it will return all the errors.

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