backoff
backoff copied to clipboard
add max retry parameter to exponential backoff
Adds a parameter to the ExponentatialBackoff allowing for the maximum number of retires to be specified, allowing for both a max retry count as well as a max duration to be specified for the backoff.
Fixes #55
same problem here, is there any will to merge this pull request?
Currently without this commit, normal retry can be worked around this:
fn retry<F, B, T, E>(max_attempts: usize, backoff: B, mut op: F) -> Result<T, backoff::Error<E>>
where
F: FnMut() -> Result<T, backoff::Error<E>>,
B: backoff::backoff::Backoff,
{
let mut attempt_count = 0;
backoff::retry(backoff, || {
let result = op();
attempt_count += 1;
if attempt_count >= max_attempts {
result.map_err(|err| match err {
backoff::Error::Permanent(err) => backoff::Error::permanent(err),
backoff::Error::Transient { err, .. } => backoff::Error::permanent(err),
})
} else {
result
}
})
}
but with future retry, it is more complicated, i have tried to using backoff::future::retry_notify and backoff::Notify, record each attempt to Notify, if the record in notify exceeds maximum, return some permanent error, but in the end, it does not work out.
Another workaround is to use a custom struct implementing Backoff
, e.g.
struct ExpBackoffWithMaxRetries {
exp: ExponentialBackoff,
retries: usize,
}
impl Backoff for ExpBackoffWithMaxRetries {
fn reset(&mut self) {
self.exp.reset();
self.retries = 0;
}
fn next_backoff(&mut self) -> Option<Duration> {
self.retries += 1;
if self.retries >= MAX_RETRIES {
self.exp.next_backoff()
} else {
None
}
}
}