/
utils.go
144 lines (105 loc) · 2.7 KB
/
utils.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
package push
import (
"regexp"
"strings"
)
var vregexp = regexp.MustCompile(`/v/\d+`)
func getTargetIdentity(path string) (string, string) {
parts := strings.Split(
strings.TrimPrefix(
vregexp.ReplaceAllString(path, ""),
"/",
),
"/",
)
prefix := ""
if len(parts) > 1 && parts[0][0] == '_' {
prefix = parts[0][1:]
parts = append([]string{}, parts[1:]...)
}
switch len(parts) {
case 1:
return parts[0], prefix
case 2:
return parts[0], prefix
default:
return parts[2], prefix
}
}
func pick(randomizer Randomizer, len int) (int, int) {
if len < 2 {
panic("pick: len must be greater than 2")
}
idxs := make([]int, len)
for i := 0; i < len; i++ {
idxs[i] = i
}
randomizer.Shuffle(len, func(i, j int) { idxs[i], idxs[j] = idxs[j], idxs[i] })
return idxs[0], idxs[1]
}
func handleAddServicePing(services servicesConfig, sp servicePing) bool {
if sp.Status == entityStatusGoodbye {
panic("handleAddServicePing received a goodbye service ping")
}
srv, ok := services[sp.Key()]
if !ok {
srv = newService(sp.Key())
services[sp.Key()] = srv
}
// In any case we poke the endpoint. This will
// only do something if the endpoint is already
// registered.
defer srv.pokeEndpoint(sp.Endpoint, sp.Load)
if srv.hasEndpoint(sp.Endpoint) {
return false
}
// We update the info to the latest.
srv.routes = sp.Routes
srv.versions = sp.Versions
// We register the new endpoint.
srv.registerEndpoint(sp.Endpoint, sp.Load, sp.APILimiters)
return true
}
func handleRemoveServicePing(services servicesConfig, sp servicePing) bool {
if sp.Status == entityStatusHello {
panic("handleRemoveServicePing received a hello service ping")
}
srv, ok := services[sp.Key()]
if !ok {
return false
}
if !srv.hasEndpoint(sp.Endpoint) {
return false
}
srv.unregisterEndpoint(sp.Endpoint)
if len(srv.getEndpoints()) > 0 {
return true
}
delete(services, sp.Key())
return true
}
func resyncRoutes(services servicesConfig, includePrivate bool, events map[string]string) map[string][]*endpointInfo {
apis := map[string][]*endpointInfo{}
for serviceName, config := range services {
name, prefix := extractPrefix(serviceName)
for _, routes := range config.routes {
for _, route := range routes {
if !route.Private || includePrivate {
apis[prefix+"/"+route.Identity] = append([]*endpointInfo{}, config.getEndpoints()...)
}
}
}
if api, ok := events[name]; ok {
apis[prefix+"/"+api] = append([]*endpointInfo{}, config.getEndpoints()...)
}
}
return apis
}
func extractPrefix(key string) (name string, prefix string) {
name = key
if parts := strings.SplitN(key, "/", 2); len(parts) == 2 {
prefix = parts[0]
name = parts[1]
}
return name, prefix
}