/
retry_config.go
91 lines (77 loc) · 2.42 KB
/
retry_config.go
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
package client
import (
"math/rand"
"time"
)
const (
defaultInitialDelay = 500 * time.Millisecond
defaultMaxDelay = 60 * time.Second
defaultMaxElapsedTime = 3 * time.Minute
defaultMultiplier = 1.5
defaultRandomizationFactor = 0.5
)
// RetryConfig contains exponential backoff parameters for retrying
// connections. In most cases, the default values are good enough.
type RetryConfig struct {
// InitialDelay is the delay after which the first reconnect
// attempt takes place.
// Default = 500 * time.Millisecond
InitialDelay time.Duration
// MaxDelay is the maximum possible delay between two consecutive
// reconnect attempts.
// Default = 60 * time.Second
MaxDelay time.Duration
// MaxElapsedTime is the time after which reconnect will time out
// Default = 3 * time.Minute
MaxElapsedTime time.Duration
// Multplier is the rate at which the delay will increase
// Default = 1.5
Multiplier float64
// RandomizationFactor is the extent to which the delay values will be randomized
// Default = 0.5
RandomizationFactor float64
}
// NextDelay calculates the new retry delay based on the current delay.
func (r RetryConfig) nextDelay(currentDelay time.Duration) time.Duration {
// check if current interval is max interval
// avoid calculation
if currentDelay == r.MaxDelay {
return currentDelay
}
delta := r.RandomizationFactor * float64(currentDelay)
minDelay := r.Multiplier*float64(currentDelay) - delta
maxDelay := r.Multiplier*float64(currentDelay) + delta
nextDelay := minDelay + (rand.Float64() * (maxDelay - minDelay + 1))
Delay := time.Duration(nextDelay)
if Delay > r.MaxDelay {
Delay = r.MaxDelay
}
return Delay
}
// initializeRetryValues returns a copy of this RetryConfig with nonzero
// default values replacing nil values.
func (r RetryConfig) withDefaultValues() RetryConfig {
conf := RetryConfig{
InitialDelay: r.InitialDelay,
MaxDelay: r.MaxDelay,
MaxElapsedTime: r.MaxElapsedTime,
Multiplier: r.Multiplier,
RandomizationFactor: r.RandomizationFactor,
}
if r.InitialDelay == 0 {
conf.InitialDelay = defaultInitialDelay
}
if r.MaxDelay == 0 {
conf.MaxDelay = defaultMaxDelay
}
if r.MaxElapsedTime == 0 {
conf.MaxElapsedTime = defaultMaxElapsedTime
}
if r.Multiplier < 1.0 {
conf.Multiplier = defaultMultiplier
}
if r.RandomizationFactor == 0 {
conf.RandomizationFactor = defaultRandomizationFactor
}
return conf
}