-
Notifications
You must be signed in to change notification settings - Fork 776
/
backoff.go
120 lines (102 loc) · 3.71 KB
/
backoff.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
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
package utils
import (
"fmt"
"time"
)
const (
DefaultInitialInterval = 500 * time.Millisecond
DefaultMultiplier = 1.5
DefaultMaxInterval = 300 * time.Second
DefaultMaxCount = 30
)
type backoff struct {
// InitialInterval is the first interval of backoff
InitialInterval time.Duration
// MaxInterval defines the maximum Backoff Interval can be
// After that, NextExist() returns false
MaxInterval time.Duration
// Multiplier defines the multiplier applied on current backoff interval
Multiplier float64
// MaxCount defines the maximum retries to be attempted
// After that, NextExists() returns false
MaxCount float64
currentbackoff time.Duration
currentCount float64
}
// NewBackOff returns a new backoff struct with initialized values
func NewBackOff(initialInterval time.Duration, maxInterval time.Duration, multiplier float64, maxCount float64) (*backoff, error) {
if multiplier < 0 || maxInterval < 0 || initialInterval < 0 || maxCount < 0 {
return &backoff{}, fmt.Errorf("negative value for multiplier and max internal not allowed")
}
return &backoff{
MaxInterval: maxInterval,
Multiplier: multiplier,
InitialInterval: initialInterval,
currentbackoff: DefaultInitialInterval,
currentCount: 0,
}, nil
}
// NewDefaultBackOff returns new backoff struct with default values
func NewDefaultBackOff() *backoff {
return &backoff{
MaxInterval: DefaultMaxInterval,
Multiplier: DefaultMultiplier,
InitialInterval: DefaultInitialInterval,
MaxCount: DefaultMaxCount,
currentbackoff: DefaultInitialInterval,
currentCount: 0,
}
}
// GetMultiplier returns multiplier of current backoff
func (backoff *backoff) GetMultiplier() float64 {
return backoff.Multiplier
}
// GetMaxInterval return MaxInterval of current backoff
func (backoff *backoff) GetMaxInterval() time.Duration {
return backoff.MaxInterval
}
// GetInitialInterval returns the InitialInterval of current backoff
func (backoff *backoff) GetInitialInterval() time.Duration {
return backoff.InitialInterval
}
// GetMaxCount returns the MaxCount of current backoff
func (backoff *backoff) GetMaxCount() float64 {
return backoff.MaxCount
}
// SetMaxCount updates the MaxCount of pre-created backoff
func (backoff *backoff) SetMaxCount(maxCount float64) {
backoff.MaxCount = maxCount
}
// SetMultiplier updates the Multiplier of pre-created backoff
func (backoff *backoff) SetMultiplier(multiplier float64) {
backoff.Multiplier = multiplier
}
// SetMaxInterval updates the MaxInterval of pre-created backoff
func (backoff *backoff) SetMaxInterval(maxInterval time.Duration) {
backoff.MaxInterval = maxInterval
}
// SetInitialInterval updates the InitialInterval of pre-created backoff
func (backoff *backoff) SetInitialInterval(initialInterval time.Duration) {
backoff.InitialInterval = initialInterval
}
// GetCurrentBackoffDuration returns the time.Duration for current backoff time determined
func (backoff *backoff) GetCurrentBackoffDuration() time.Duration {
return backoff.currentbackoff
}
// GetCurrentCount returns the float64 with current retry count
func (backoff *backoff) GetCurrentCount() float64 {
return backoff.currentCount
}
// GetNext returns time.Duration to add sleep for current retry
func (backoff *backoff) GetNext() time.Duration {
backoff.currentbackoff = time.Duration(float64(backoff.currentbackoff) * backoff.Multiplier)
backoff.currentCount = backoff.currentCount + 1
return backoff.currentbackoff
}
// NextExists returns boolean representing the status of next backoff duration
func (backoff *backoff) NextExists() bool {
if backoff.currentbackoff*time.Duration(backoff.Multiplier) > backoff.MaxInterval || backoff.currentCount > backoff.MaxCount {
return false
}
return true
}