-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexponential.go
More file actions
73 lines (60 loc) · 1.75 KB
/
exponential.go
File metadata and controls
73 lines (60 loc) · 1.75 KB
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
// SPDX-FileCopyrightText: 2023 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0
package retry
import (
"time"
)
// exponential is the main implementing type for Policy.
type exponential struct {
corePolicy
rand func(int64) int64
initial time.Duration
previous time.Duration
jitter float64
multiplier float64
maxInterval time.Duration
}
// nextBaseInterval computes the next un-jittered retry interval
// and sets up the next interval to use. On the first call, this
// method simply returns the initial interval. Subsequent calls
// return intervals that grow exponentially using the multiplier as
// a base. If no multiplier is set, this method just returns the
// initial interval every time.
func (e *exponential) nextBaseInterval() (base time.Duration) {
if e.previous > 0 {
base = e.previous
if e.multiplier > 1.0 {
base = time.Duration(float64(base) * e.multiplier)
}
if e.maxInterval > 0 && base > e.maxInterval {
base = e.maxInterval
}
} else {
base = e.initial
}
e.previous = base
return
}
// jitterize computes a random interval using the jitter value. If jitter is
// nonpositive, this method returns base subject to the max interval.
func (e *exponential) jitterize(base time.Duration) (next time.Duration) {
next = base
if e.jitter > 0.0 {
delta := int64(float64(next) * e.jitter)
// choose a random value in the range [next-delta, next+delta]
next = next - time.Duration(delta) + time.Duration(e.rand(2*delta+1))
}
if e.maxInterval > 0 && next > e.maxInterval {
next = e.maxInterval
}
return
}
func (e *exponential) Next() (time.Duration, bool) {
if !e.withinLimits() {
return 0, false
}
e.retryCount++
return e.jitterize(
e.nextBaseInterval(),
), true
}