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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
mod exponential;
mod fixed;
mod limited;
mod randomized;
use super::{ResponseError, RetriedStatsInfo, RetryDecision};
use auto_impl::auto_impl;
use dyn_clonable::clonable;
use qiniu_http::RequestParts as HttpRequestParts;
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
time::Duration,
};
#[clonable]
#[auto_impl(&, &mut, Box, Rc, Arc)]
pub trait Backoff: Clone + Debug + Sync + Send {
fn time(&self, request: &mut HttpRequestParts, opts: BackoffOptions) -> GotBackoffDuration;
}
#[derive(Copy, Debug, Clone)]
pub struct BackoffOptions<'a> {
retry_decision: RetryDecision,
response_error: &'a ResponseError,
retried: &'a RetriedStatsInfo,
}
impl<'a> BackoffOptions<'a> {
#[inline]
pub fn builder(response_error: &'a ResponseError, retried: &'a RetriedStatsInfo) -> BackoffOptionsBuilder<'a> {
BackoffOptionsBuilder::new(response_error, retried)
}
#[inline]
pub fn retry_decision(&self) -> RetryDecision {
self.retry_decision
}
#[inline]
pub fn response_error(&self) -> &ResponseError {
self.response_error
}
#[inline]
pub fn retried(&self) -> &RetriedStatsInfo {
self.retried
}
}
#[derive(Copy, Debug, Clone)]
pub struct BackoffOptionsBuilder<'a>(BackoffOptions<'a>);
impl<'a> BackoffOptionsBuilder<'a> {
#[inline]
pub fn new(response_error: &'a ResponseError, retried: &'a RetriedStatsInfo) -> Self {
Self(BackoffOptions {
response_error,
retried,
retry_decision: Default::default(),
})
}
#[inline]
pub fn retry_decision(&mut self, decision: RetryDecision) -> &mut Self {
self.0.retry_decision = decision;
self
}
pub fn build(&self) -> BackoffOptions<'a> {
self.0
}
}
#[derive(Debug)]
pub struct GotBackoffDuration(Duration);
impl GotBackoffDuration {
#[inline]
pub fn duration(&self) -> Duration {
self.0
}
#[inline]
pub fn duration_mut(&mut self) -> &mut Duration {
&mut self.0
}
}
impl From<Duration> for GotBackoffDuration {
#[inline]
fn from(duration: Duration) -> Self {
Self(duration)
}
}
impl From<GotBackoffDuration> for Duration {
#[inline]
fn from(backoff_duration: GotBackoffDuration) -> Self {
backoff_duration.0
}
}
impl AsRef<Duration> for GotBackoffDuration {
#[inline]
fn as_ref(&self) -> &Duration {
&self.0
}
}
impl AsMut<Duration> for GotBackoffDuration {
#[inline]
fn as_mut(&mut self) -> &mut Duration {
&mut self.0
}
}
impl Deref for GotBackoffDuration {
type Target = Duration;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for GotBackoffDuration {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub use exponential::ExponentialBackoff;
pub use fixed::{FixedBackoff, NO_BACKOFF};
pub use limited::LimitedBackoff;
pub use randomized::{RandomizedBackoff, Ratio};