forked from go-chassis/go-chassis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
circuit_breaker_event_listener.go
executable file
·94 lines (84 loc) · 3.27 KB
/
circuit_breaker_event_listener.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
package eventlistener
import (
"regexp"
"strings"
"github.com/go-chassis/go-archaius/core"
"github.com/go-chassis/go-chassis/control/archaius"
"github.com/go-chassis/go-chassis/core/common"
"github.com/go-chassis/go-chassis/core/config"
"github.com/go-chassis/go-chassis/core/lager"
"github.com/go-chassis/go-chassis/third_party/forked/afex/hystrix-go/hystrix"
)
// constants for consumer isolation, circuit breaker, fallback keys
const (
// ConsumerIsolationKey is a variable of type string
ConsumerIsolationKey = "cse.isolation"
ConsumerCircuitbreakerKey = "cse.circuitBreaker"
ConsumerFallbackKey = "cse.fallback"
ConsumerFallbackPolicyKey = "cse.fallbackpolicy"
regex4normal = "cse\\.(isolation|circuitBreaker|fallback|fallbackpolicy)\\.Consumer\\.(.*)\\.(timeout|timeoutInMilliseconds|maxConcurrentRequests|enabled|forceOpen|forceClosed|sleepWindowInMilliseconds|requestVolumeThreshold|errorThresholdPercentage|enabled|maxConcurrentRequests|policy)\\.(.+)"
regex4mesher = "cse\\.(isolation|circuitBreaker|fallback|fallbackpolicy)\\.(.+)\\.Consumer\\.(.*)\\.(timeout|timeoutInMilliseconds|maxConcurrentRequests|enabled|forceOpen|forceClosed|sleepWindowInMilliseconds|requestVolumeThreshold|errorThresholdPercentage|enabled|maxConcurrentRequests|policy)\\.(.+)"
)
//CircuitBreakerEventListener is a struct with one string variable
type CircuitBreakerEventListener struct {
Key string
}
//Event is a method which triggers flush circuit
func (e *CircuitBreakerEventListener) Event(event *core.Event) {
lager.Logger.Infof("Circuit key event: %v", event.Key)
if err := config.ReadHystrixFromArchaius(); err != nil {
lager.Logger.Error("can not unmarshal new cb config", err)
}
archaius.SaveToCBCache(config.GetHystrixConfig())
switch event.EventType {
case common.Update:
FlushCircuitByKey(event.Key)
case common.Create:
FlushCircuitByKey(event.Key)
case common.Delete:
FlushCircuitByKey(event.Key)
}
}
//FlushCircuitByKey is a function used to flush for a particular key
func FlushCircuitByKey(key string) {
sourceName, serviceName := GetNames(key)
cmdName := GetCircuitName(sourceName, serviceName)
if cmdName == common.Consumer {
lager.Logger.Info("Global Key changed For circuit: [" + cmdName + "]")
hystrix.Flush()
} else {
lager.Logger.Info("Specific Key changed For circuit: [" + cmdName + "]")
hystrix.FlushByName(cmdName)
}
}
//GetNames is function
func GetNames(key string) (string, string) {
regNormal := regexp.MustCompile(regex4normal)
regMesher := regexp.MustCompile(regex4mesher)
var sourceName string
var serviceName string
if regNormal.MatchString(key) {
s := regNormal.FindStringSubmatch(key)
lager.Logger.Debug("Normal Key")
return "", s[2]
}
if regMesher.MatchString(key) {
s := regMesher.FindStringSubmatch(key)
lager.Logger.Debug("Mesher Key")
return s[2], s[3]
}
return sourceName, serviceName
}
//GetCircuitName is a function used to get circuit names
func GetCircuitName(sourceName, serviceName string) string {
if sourceName != "" {
return strings.Join([]string{sourceName, "Consumer", serviceName}, ".")
}
if sourceName == "" && serviceName != "" {
return strings.Join([]string{"Consumer", serviceName}, ".")
}
if sourceName == "" && serviceName == "" {
return common.Consumer
}
return ""
}