/
back_off_policy.go
117 lines (104 loc) · 3.44 KB
/
back_off_policy.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
package tea
import (
"math"
"math/rand"
)
type BackoffPolicy interface {
GetDelayTimeMillis(ctx *RetryPolicyContext) *int64
}
func NewBackoffPolicy(options map[string]interface{}) (backoffPolicy BackoffPolicy) {
policy := StringValue(TransInterfaceToString(options["policy"]))
switch policy {
case "Fixed":
backoffPolicy = &FixedBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
}
return
case "Random":
backoffPolicy = &RandomBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
Cap: TransInterfaceToInt64(options["cap"]),
}
return
case "Exponential":
backoffPolicy = &ExponentialBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
Cap: TransInterfaceToInt64(options["cap"]),
}
return
case "EqualJitter":
backoffPolicy = &EqualJitterBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
Cap: TransInterfaceToInt64(options["cap"]),
}
return
case "ExponentialWithEqualJitter":
backoffPolicy = &EqualJitterBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
Cap: TransInterfaceToInt64(options["cap"]),
}
return
case "FullJitter":
backoffPolicy = &FullJitterBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
Cap: TransInterfaceToInt64(options["cap"]),
}
return
case "ExponentialWithFullJitter":
backoffPolicy = &FullJitterBackoffPolicy{
Period: TransInterfaceToInt(options["period"]),
Cap: TransInterfaceToInt64(options["cap"]),
}
return
}
return nil
}
type FixedBackoffPolicy struct {
Period *int
}
func (fixedBackoff *FixedBackoffPolicy) GetDelayTimeMillis(ctx *RetryPolicyContext) *int64 {
return Int64(int64(IntValue(fixedBackoff.Period)))
}
type RandomBackoffPolicy struct {
Period *int
Cap *int64
}
func (randomBackoff *RandomBackoffPolicy) GetDelayTimeMillis(ctx *RetryPolicyContext) *int64 {
if randomBackoff.Cap == nil {
randomBackoff.Cap = Int64(20 * 1000)
}
ceil := math.Min(float64(*randomBackoff.Cap), float64(IntValue(randomBackoff.Period))*float64(IntValue(ctx.RetriesAttempted)))
return Int64(int64(rand.Float64() * ceil))
}
type ExponentialBackoffPolicy struct {
Period *int
Cap *int64
}
func (exponentialBackoff *ExponentialBackoffPolicy) GetDelayTimeMillis(ctx *RetryPolicyContext) *int64 {
if exponentialBackoff.Cap == nil {
exponentialBackoff.Cap = Int64(3 * 24 * 60 * 60 * 1000)
}
return Int64(int64(math.Min(float64(*exponentialBackoff.Cap), float64(IntValue(exponentialBackoff.Period))*math.Pow(2.0, float64(IntValue(ctx.RetriesAttempted))))))
}
type EqualJitterBackoffPolicy struct {
Period *int
Cap *int64
}
func (equalJitterBackoff *EqualJitterBackoffPolicy) GetDelayTimeMillis(ctx *RetryPolicyContext) *int64 {
if equalJitterBackoff.Cap == nil {
equalJitterBackoff.Cap = Int64(3 * 24 * 60 * 60 * 1000)
}
ceil := math.Min(float64(*equalJitterBackoff.Cap), float64(IntValue(equalJitterBackoff.Period))*math.Pow(2.0, float64(IntValue(ctx.RetriesAttempted))))
return Int64(int64(ceil/2 + rand.Float64()*(ceil/2+1)))
}
type FullJitterBackoffPolicy struct {
Period *int
Cap *int64
}
func (fullJitterBackof *FullJitterBackoffPolicy) GetDelayTimeMillis(ctx *RetryPolicyContext) *int64 {
if fullJitterBackof.Cap == nil {
fullJitterBackof.Cap = Int64(3 * 24 * 60 * 60 * 1000)
}
ceil := math.Min(float64(*fullJitterBackof.Cap), float64(IntValue(fullJitterBackof.Period))*math.Pow(2.0, float64(IntValue(ctx.RetriesAttempted))))
return Int64(int64(rand.Float64() * ceil))
}