1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use std::time::Duration;
use futures_retry::{ErrorHandler, RetryPolicy};
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;
use rusoto_core::RusotoError;
pub struct RetryHandler {
attempt: u8,
max_attempts: u8,
rng: XorShiftRng,
}
impl RetryHandler {
pub fn new(attempts: u8) -> Self {
Self {
attempt: 0,
max_attempts: attempts,
rng: XorShiftRng::from_seed([0; 16]),
}
}
}
impl<E> ErrorHandler<RusotoError<E>> for RetryHandler {
type OutError = RusotoError<E>;
fn handle(&mut self, e: RusotoError<E>) -> RetryPolicy<RusotoError<E>> {
if self.attempt == self.max_attempts {
return RetryPolicy::ForwardError(e);
}
self.attempt += 1;
match e {
RusotoError::HttpDispatch(_) | RusotoError::Unknown(_) => {
let jitter: u64 = self.rng.gen_range(10, 50);
let backoff = jitter + (self.attempt as u64 * 10);
RetryPolicy::WaitRetry(Duration::from_millis(backoff))
}
_ => RetryPolicy::ForwardError(e)
}
}
fn ok(&mut self) {
self.attempt = 0;
}
}