@@ -56,131 +56,47 @@ type ExponentialBackOff struct {
56
56
RandomizationFactor float64
57
57
Multiplier float64
58
58
MaxInterval time.Duration
59
- // After MaxElapsedTime the ExponentialBackOff stops.
60
- // It never stops if MaxElapsedTime == 0.
61
- MaxElapsedTime time.Duration
62
- Clock Clock
63
59
64
60
currentInterval time.Duration
65
- startTime time.Time
66
61
}
67
62
68
- // Clock is an interface that returns current time for BackOff.
69
- type Clock interface {
70
- Now () time.Time
71
- }
72
-
73
- // ExponentialBackOffOpts is a function type used to configure ExponentialBackOff options.
74
- type ExponentialBackOffOpts func (* ExponentialBackOff )
75
-
76
63
// Default values for ExponentialBackOff.
77
64
const (
78
65
DefaultInitialInterval = 500 * time .Millisecond
79
66
DefaultRandomizationFactor = 0.5
80
67
DefaultMultiplier = 1.5
81
68
DefaultMaxInterval = 60 * time .Second
82
- DefaultMaxElapsedTime = 15 * time .Minute
83
69
)
84
70
85
71
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
86
- func NewExponentialBackOff (opts ... ExponentialBackOffOpts ) * ExponentialBackOff {
87
- b := & ExponentialBackOff {
72
+ func NewExponentialBackOff () * ExponentialBackOff {
73
+ return & ExponentialBackOff {
88
74
InitialInterval : DefaultInitialInterval ,
89
75
RandomizationFactor : DefaultRandomizationFactor ,
90
76
Multiplier : DefaultMultiplier ,
91
77
MaxInterval : DefaultMaxInterval ,
92
- MaxElapsedTime : DefaultMaxElapsedTime ,
93
- Clock : SystemClock ,
94
- }
95
- for _ , fn := range opts {
96
- fn (b )
97
- }
98
- b .Reset ()
99
- return b
100
- }
101
-
102
- // WithInitialInterval sets the initial interval between retries.
103
- func WithInitialInterval (duration time.Duration ) ExponentialBackOffOpts {
104
- return func (ebo * ExponentialBackOff ) {
105
- ebo .InitialInterval = duration
106
- }
107
- }
108
-
109
- // WithRandomizationFactor sets the randomization factor to add jitter to intervals.
110
- func WithRandomizationFactor (randomizationFactor float64 ) ExponentialBackOffOpts {
111
- return func (ebo * ExponentialBackOff ) {
112
- ebo .RandomizationFactor = randomizationFactor
113
- }
114
- }
115
-
116
- // WithMultiplier sets the multiplier for increasing the interval after each retry.
117
- func WithMultiplier (multiplier float64 ) ExponentialBackOffOpts {
118
- return func (ebo * ExponentialBackOff ) {
119
- ebo .Multiplier = multiplier
120
- }
121
- }
122
-
123
- // WithMaxInterval sets the maximum interval between retries.
124
- func WithMaxInterval (duration time.Duration ) ExponentialBackOffOpts {
125
- return func (ebo * ExponentialBackOff ) {
126
- ebo .MaxInterval = duration
127
78
}
128
79
}
129
80
130
- // WithMaxElapsedTime sets the maximum total time for retries.
131
- func WithMaxElapsedTime (duration time.Duration ) ExponentialBackOffOpts {
132
- return func (ebo * ExponentialBackOff ) {
133
- ebo .MaxElapsedTime = duration
134
- }
135
- }
136
-
137
- // WithClockProvider sets the clock used to measure time.
138
- func WithClockProvider (clock Clock ) ExponentialBackOffOpts {
139
- return func (ebo * ExponentialBackOff ) {
140
- ebo .Clock = clock
141
- }
142
- }
143
-
144
- type systemClock struct {}
145
-
146
- func (t systemClock ) Now () time.Time {
147
- return time .Now ()
148
- }
149
-
150
- // SystemClock implements Clock interface that uses time.Now().
151
- var SystemClock = systemClock {}
152
-
153
81
// Reset the interval back to the initial retry interval and restarts the timer.
154
82
// Reset must be called before using b.
155
83
func (b * ExponentialBackOff ) Reset () {
156
84
b .currentInterval = b .InitialInterval
157
- b .startTime = b .Clock .Now ()
158
85
}
159
86
160
87
// NextBackOff calculates the next backoff interval using the formula:
161
88
//
162
89
// Randomized interval = RetryInterval * (1 ± RandomizationFactor)
163
90
func (b * ExponentialBackOff ) NextBackOff () time.Duration {
164
- // Make sure we have not gone over the maximum elapsed time.
165
- elapsed := b .GetElapsedTime ()
91
+ if b .currentInterval == 0 {
92
+ b .currentInterval = b .InitialInterval
93
+ }
94
+
166
95
next := getRandomValueFromInterval (b .RandomizationFactor , rand .Float64 (), b .currentInterval )
167
96
b .incrementCurrentInterval ()
168
- if b .MaxElapsedTime != 0 && elapsed + next > b .MaxElapsedTime {
169
- return Stop
170
- }
171
97
return next
172
98
}
173
99
174
- // GetElapsedTime returns the elapsed time since an ExponentialBackOff instance
175
- // is created and is reset when Reset() is called.
176
- //
177
- // The elapsed time is computed using time.Now().UnixNano(). It is
178
- // safe to call even while the backoff policy is used by a running
179
- // ticker.
180
- func (b * ExponentialBackOff ) GetElapsedTime () time.Duration {
181
- return b .Clock .Now ().Sub (b .startTime )
182
- }
183
-
184
100
// Increments the current interval by multiplying it with the multiplier.
185
101
func (b * ExponentialBackOff ) incrementCurrentInterval () {
186
102
// Check for overflow, if overflow is detected set the current interval to the max interval.
0 commit comments