/
util.go
210 lines (174 loc) · 3.74 KB
/
util.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package pylon
import (
"sync"
"log"
"fmt"
"io"
)
type SharedInt struct {
*sync.RWMutex
value int
}
func NewSharedInt(v int) SharedInt {
return SharedInt{
&sync.RWMutex{},
v,
}
}
func (c *SharedInt) Get() int {
c.RLock()
defer c.RUnlock()
return c.value
}
func (c *SharedInt) Set(v int) int {
c.Lock()
defer c.Unlock()
prev := c.value
c.value = v
return prev
}
const (
LOG_DEBUG int8 = 1 << 0
LOG_ERROR int8 = 1 << 1
LOG_INFO int8 = 1 << 2
LOG_VERBOSE int8 = 1 << 3
LOG_NONE int8 = 0
LOG_EXCEPT_VERBOSE int8 = LOG_DEBUG | LOG_ERROR | LOG_INFO
LOG_ALL int8 = LOG_DEBUG | LOG_ERROR | LOG_INFO | LOG_VERBOSE
)
var (
debugLogger Logger = debugFunc
errorLogger Logger = errorFunc
infoLogger Logger = infoFunc
verboseLogger Logger = verboseFunc
logMask int8 = LOG_EXCEPT_VERBOSE
)
type Logger func(...interface{})
func SetDebugLogger(l Logger) {
debugLogger = l
}
func SetErrorLogger(l Logger) {
errorLogger = l
}
func SetInfoLogger(l Logger) {
infoLogger = l
}
func SetVerboseLogger(l Logger) {
verboseLogger = l
}
func SetLogWriter(w io.Writer) {
log.SetOutput(w)
}
func SetLogLevels(mask int8) {
logMask = mask
}
func logDebug(a ...interface{}) {
if logMask & LOG_DEBUG != 0 {
debugLogger(a)
}
}
func logError(a ...interface{}) {
if logMask & LOG_ERROR != 0 {
errorLogger(a)
}
}
func logInfo(a ...interface{}) {
if logMask & LOG_INFO != 0 {
infoLogger(a)
}
}
func logVerbose(a ...interface{}) {
if logMask & LOG_VERBOSE != 0 {
verboseLogger(a)
}
}
func debugFunc(a ...interface{}) {
log.Println("- DEBUG -", a)
}
func infoFunc(a ...interface{}) {
log.Println("- INFO -", a)
}
func errorFunc(a ...interface{}) {
log.Println("- ERROR -", a)
}
func verboseFunc(a ...interface{}) {
log.Println("- VERBO -", a)
}
const (
pylonTemplate = `{{range .}}
Name: {{.Name}}
Connections: {{.CurrConn}}
Strategy: {{.Strat}}
{{range .Instances}}
Up: {{.Up}}
Host: {{.Host}}
Weight: {{.Weight}}
Connections: {{.CurrConn}}
{{end}}
{{end}}`
defaultHealthRoute = "/health"
)
type InstanceRender struct {
Up bool
Host string
Weight float32
CurrConn int
}
type ServiceRender struct {
Name string
CurrConn int
Strat Strategy
Instances []InstanceRender
}
func getRenders(p *Pylon) []ServiceRender {
renders := make([]ServiceRender, len(p.Services))
for idx, s := range p.Services {
insts := make([]InstanceRender, len(s.Instances))
for i, ins := range s.Instances {
insts[i] = InstanceRender{
Up: !s.isBlacklisted(i),
Host: ins.Host,
Weight: ins.Weight,
CurrConn: len(ins.ReqCount),
}
}
renders[idx] = ServiceRender{
Name: s.Name,
CurrConn: len(s.ReqCount),
Strat: s.Strategy,
Instances: insts,
}
}
return renders
}
const (
ErrServiceNoRouteCode = iota + 30
ErrInvalidRouteTypeCode
ErrRouteNoRouteCode
ErrServiceNoInstanceCode
ErrAllInstancesDownCode
ErrInvalidStrategyCode
ErrFailedRoundRobinCode
ErrInvalidRouteRegexCode
ErrInvalidHostCode
)
var (
ErrServiceNoRoute = NewError(ErrServiceNoRouteCode, "Service has no route")
ErrInvalidRouteType = NewError(ErrInvalidRouteTypeCode, "Route has invalid type")
ErrServiceNoInstance = NewError(ErrServiceNoInstanceCode, "Service has no instances")
ErrAllInstancesDown = NewError(ErrAllInstancesDownCode, "All instances are dead")
ErrFailedRoundRobin = NewError(ErrFailedRoundRobinCode, "No instance can be round robin picked")
)
type Error struct {
Code int
Message string
}
func (e *Error) Error() string {
return fmt.Sprintf("%s - [Error %d]", e.Message, e.Code)
}
func NewError(code int, message string) *Error {
return &Error{
code,
message,
}
}