cubefs
124 строки · 3.3 Кб
1package hystrix
2
3import (
4"sync"
5"time"
6)
7
8var (
9// DefaultTimeout is how long to wait for command to complete, in milliseconds
10DefaultTimeout = 1000
11// DefaultMaxConcurrent is how many commands of the same type can run at the same time
12DefaultMaxConcurrent = 10
13// DefaultVolumeThreshold is the minimum number of requests needed before a circuit can be tripped due to health
14DefaultVolumeThreshold = 20
15// DefaultSleepWindow is how long, in milliseconds, to wait after a circuit opens before testing for recovery
16DefaultSleepWindow = 5000
17// DefaultErrorPercentThreshold causes circuits to open once the rolling measure of errors exceeds this percent of requests
18DefaultErrorPercentThreshold = 50
19// DefaultLogger is the default logger that will be used in the Hystrix package. By default prints nothing.
20DefaultLogger = NoopLogger{}
21)
22
23type Settings struct {
24Timeout time.Duration
25MaxConcurrentRequests int
26RequestVolumeThreshold uint64
27SleepWindow time.Duration
28ErrorPercentThreshold int
29}
30
31// CommandConfig is used to tune circuit settings at runtime
32type CommandConfig struct {
33Timeout int `json:"timeout"`
34MaxConcurrentRequests int `json:"max_concurrent_requests"`
35RequestVolumeThreshold int `json:"request_volume_threshold"`
36SleepWindow int `json:"sleep_window"`
37ErrorPercentThreshold int `json:"error_percent_threshold"`
38}
39
40var circuitSettings map[string]*Settings
41var settingsMutex *sync.RWMutex
42var log logger
43
44func init() {
45circuitSettings = make(map[string]*Settings)
46settingsMutex = &sync.RWMutex{}
47log = DefaultLogger
48}
49
50// Configure applies settings for a set of circuits
51func Configure(cmds map[string]CommandConfig) {
52for k, v := range cmds {
53ConfigureCommand(k, v)
54}
55}
56
57// ConfigureCommand applies settings for a circuit
58func ConfigureCommand(name string, config CommandConfig) {
59settingsMutex.Lock()
60defer settingsMutex.Unlock()
61
62timeout := DefaultTimeout
63if config.Timeout != 0 {
64timeout = config.Timeout
65}
66
67max := DefaultMaxConcurrent
68if config.MaxConcurrentRequests != 0 {
69max = config.MaxConcurrentRequests
70}
71
72volume := DefaultVolumeThreshold
73if config.RequestVolumeThreshold != 0 {
74volume = config.RequestVolumeThreshold
75}
76
77sleep := DefaultSleepWindow
78if config.SleepWindow != 0 {
79sleep = config.SleepWindow
80}
81
82errorPercent := DefaultErrorPercentThreshold
83if config.ErrorPercentThreshold != 0 {
84errorPercent = config.ErrorPercentThreshold
85}
86
87circuitSettings[name] = &Settings{
88Timeout: time.Duration(timeout) * time.Millisecond,
89MaxConcurrentRequests: max,
90RequestVolumeThreshold: uint64(volume),
91SleepWindow: time.Duration(sleep) * time.Millisecond,
92ErrorPercentThreshold: errorPercent,
93}
94}
95
96func getSettings(name string) *Settings {
97settingsMutex.RLock()
98s, exists := circuitSettings[name]
99settingsMutex.RUnlock()
100
101if !exists {
102ConfigureCommand(name, CommandConfig{})
103s = getSettings(name)
104}
105
106return s
107}
108
109func GetCircuitSettings() map[string]*Settings {
110copy := make(map[string]*Settings)
111
112settingsMutex.RLock()
113for key, val := range circuitSettings {
114copy[key] = val
115}
116settingsMutex.RUnlock()
117
118return copy
119}
120
121// SetLogger configures the logger that will be used. This only applies to the hystrix package.
122func SetLogger(l logger) {
123log = l
124}
125