/
init.go
108 lines (91 loc) · 2.73 KB
/
init.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
package breaker
import (
"strings"
"sync"
"sync/atomic"
"github.com/yunfeiyang1916/toolkit/logging"
)
type watcher struct {
breakers atomic.Value
}
var globalWatcher watcher
type BreakerConfig struct {
Name string `toml:"name"`
ErrorPercentThreshold int `toml:"error_percent_threshold"`
ConsecutiveErrorThreshold int `toml:"consecutive_error_threshold"`
MinSamples int `toml:"minsamples"`
Break bool `toml:"break"`
}
func init() {
globalWatcher.breakers.Store(&sync.Map{})
}
// 有配置变更, 每次构造新的breaker
func initBreaker(c BreakerConfig) *Breaker {
Configure(c.Name, &c)
brk := NewBreakerWithOptions(&Options{
Name: c.Name,
})
if c.Break {
brk.Break()
}
logging.GenLogf("on breaker, name:%s, break:%v, error_percent:%d, consecutive_error:%d, minsamples:%d", c.Name, c.Break, c.ErrorPercentThreshold, c.ConsecutiveErrorThreshold, c.MinSamples)
return brk
}
// 重新加载配置使用
func initBreakers(configs []BreakerConfig) {
if len(configs) == 0 {
return
}
breakers := &sync.Map{}
for _, v := range configs {
lastVersionConfigs.Store(v.Name, v)
if strings.Contains(v.Name, "*") {
templateConfigs.Store(v.Name, &BreakerConfig{
Name: v.Name,
ErrorPercentThreshold: v.ErrorPercentThreshold,
ConsecutiveErrorThreshold: v.ConsecutiveErrorThreshold,
MinSamples: v.MinSamples,
Break: v.Break,
})
logging.GenLogf("on breaker, template name:%s, break:%v, error_percent:%d, consecutive_error:%d, minsamples:%d", v.Name, v.Break, v.ErrorPercentThreshold, v.ConsecutiveErrorThreshold, v.MinSamples)
continue
}
breakers.Store(v.Name, initBreaker(v))
}
globalWatcher.breakers.Store(breakers)
}
// 初始化时使用
func injectBreakConfig(configs []BreakerConfig) {
if len(configs) == 0 {
return
}
watcher := globalWatcher.breakers.Load().(*sync.Map)
for _, v := range configs {
lastVersionConfigs.Store(v.Name, v)
if strings.Contains(v.Name, "*") {
if _, ok := templateConfigs.Load(v.Name); !ok {
templateConfigs.Store(v.Name, &BreakerConfig{
Name: v.Name,
ErrorPercentThreshold: v.ErrorPercentThreshold,
ConsecutiveErrorThreshold: v.ConsecutiveErrorThreshold,
MinSamples: v.MinSamples,
Break: v.Break,
})
continue
}
}
if _, ok := watcher.Load(v.Name); !ok {
watcher.Store(v.Name, initBreaker(v))
}
}
}
func InitBreakers(configs []BreakerConfig) {
initBreakers(configs)
}
func GetBreaker(name string) *Breaker {
watcher := globalWatcher.breakers.Load().(*sync.Map)
if val, ok := watcher.Load(name); ok {
return val.(*Breaker)
}
return nil
}