-
Notifications
You must be signed in to change notification settings - Fork 476
/
settings.go
115 lines (95 loc) · 2.96 KB
/
settings.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
package hystrix
import (
"sync"
"time"
)
var (
// DefaultTimeout is how long to wait for command to complete, in milliseconds
DefaultTimeout = 1000
// DefaultMaxConcurrent is how many commands of the same type can run at the same time
DefaultMaxConcurrent = 10
// DefaultVolumeThreshold is the minimum number of requests needed before a circuit can be tripped due to health
DefaultVolumeThreshold = 20
// DefaultSleepWindow is how long, in milliseconds, to wait after a circuit opens before testing for recovery
DefaultSleepWindow = 5000
// DefaultErrorPercentThreshold causes circuits to open once the rolling measure of errors exceeds this percent of requests
DefaultErrorPercentThreshold = 50
)
type Settings struct {
Timeout time.Duration
MaxConcurrentRequests int
RequestVolumeThreshold uint64
SleepWindow time.Duration
ErrorPercentThreshold int
}
// CommandConfig is used to tune circuit settings at runtime
type CommandConfig struct {
Timeout int `json:"timeout"`
MaxConcurrentRequests int `json:"max_concurrent_requests"`
RequestVolumeThreshold int `json:"request_volume_threshold"`
SleepWindow int `json:"sleep_window"`
ErrorPercentThreshold int `json:"error_percent_threshold"`
}
var circuitSettings map[string]*Settings
var settingsMutex *sync.RWMutex
func init() {
circuitSettings = make(map[string]*Settings)
settingsMutex = &sync.RWMutex{}
}
// Configure applies settings for a set of circuits
func Configure(cmds map[string]CommandConfig) {
for k, v := range cmds {
ConfigureCommand(k, v)
}
}
// ConfigureCommand applies settings for a circuit
func ConfigureCommand(name string, config CommandConfig) {
settingsMutex.Lock()
defer settingsMutex.Unlock()
timeout := DefaultTimeout
if config.Timeout != 0 {
timeout = config.Timeout
}
max := DefaultMaxConcurrent
if config.MaxConcurrentRequests != 0 {
max = config.MaxConcurrentRequests
}
volume := DefaultVolumeThreshold
if config.RequestVolumeThreshold != 0 {
volume = config.RequestVolumeThreshold
}
sleep := DefaultSleepWindow
if config.SleepWindow != 0 {
sleep = config.SleepWindow
}
errorPercent := DefaultErrorPercentThreshold
if config.ErrorPercentThreshold != 0 {
errorPercent = config.ErrorPercentThreshold
}
circuitSettings[name] = &Settings{
Timeout: time.Duration(timeout) * time.Millisecond,
MaxConcurrentRequests: max,
RequestVolumeThreshold: uint64(volume),
SleepWindow: time.Duration(sleep) * time.Millisecond,
ErrorPercentThreshold: errorPercent,
}
}
func getSettings(name string) *Settings {
settingsMutex.RLock()
s, exists := circuitSettings[name]
settingsMutex.RUnlock()
if !exists {
ConfigureCommand(name, CommandConfig{})
s = getSettings(name)
}
return s
}
func GetCircuitSettings() map[string]*Settings {
copy := make(map[string]*Settings)
settingsMutex.RLock()
for key, val := range circuitSettings {
copy[key] = val
}
settingsMutex.RUnlock()
return copy
}