Skip to content

Commit 35e4285

Browse files
committed
WIP: use stable client indexes to pick target vtgates
Signed-off-by: Henry Robinson <hrobinson@slack-corp.com>
1 parent 0b70c76 commit 35e4285

File tree

2 files changed

+253
-2
lines changed

2 files changed

+253
-2
lines changed

go/vt/vtgateproxy/discovery.go

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"io"
2424
"math/rand"
25+
"net/http"
2526
"os"
2627
"sort"
2728
"sync"
@@ -319,11 +320,16 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
319320
// target lock and then comparing the previous targets with the current
320321
// targets and only resetting pools which disappear.
321322
targetCount.ResetAll()
322-
323+
idx := getClientIndex()
323324
for poolType := range targets {
324325
b.sorter.shuffleSort(targets[poolType], b.affinityField, b.affinityValue)
325326
if len(targets[poolType]) > *numConnections {
326-
targets[poolType] = targets[poolType][:b.numConnections]
327+
targetPool := []targetHost{}
328+
for i := 0; i < 4; i++ {
329+
targetPool = append(targetPool, targets[poolType][(idx+i)%len(targets[poolType])])
330+
}
331+
log.Infof("My index is: %d, picking %+v", idx, targetPool)
332+
targets[poolType] = targetPool
327333
}
328334
targetCount.Set(poolType, int64(len(targets[poolType])))
329335
}
@@ -393,6 +399,66 @@ func (s *shuffleSorter) shuffleSort(targets []targetHost, affinityField, affinit
393399
}
394400
}
395401

402+
func getWebappDiscovery() *RotorJson {
403+
payload := `{"node":{"cluster":"webapp"}, "resource_names":["hhvm-metrics@dev-us-east-1"]}`
404+
res, err := http.Post("http://rotor-http-dev-us-east-1.internal.ec2.tinyspeck.com:50001/v3/discovery:endpoints", "application/json", bytes.NewBuffer([]byte(payload)))
405+
if err != nil {
406+
return nil
407+
}
408+
// fmt.Println("Non-nil response")
409+
if res.StatusCode != 200 {
410+
return nil
411+
}
412+
// fmt.Println("200 response")
413+
body, err := io.ReadAll(res.Body)
414+
if err != nil {
415+
return nil
416+
}
417+
// fmt.Printf("Unmarshalling %+v\n", string(body))
418+
result := RotorJson{}
419+
json.Unmarshal(body, &result)
420+
// fmt.Printf("%+v\n", result)
421+
return &result
422+
}
423+
424+
func getHosts() []string {
425+
discovery := getWebappDiscovery()
426+
nodenames := []string{}
427+
for _, r := range discovery.Resources {
428+
for _, e := range r.Endpoints {
429+
for _, lb := range e.LBEndpoints {
430+
node := lb.Metadata.FilterMetadata.EnvoyLB
431+
nodenames = append(nodenames, node.NodeName)
432+
fmt.Printf("Nodename: %+v\n", node.NodeName)
433+
}
434+
}
435+
}
436+
437+
return nodenames
438+
}
439+
440+
func getClientIndex() int {
441+
nodenames := getHosts()
442+
sort.Strings(nodenames)
443+
hostname, err := os.Hostname()
444+
fmt.Printf("Hostname: %s\n", hostname)
445+
if err != nil {
446+
return -1
447+
}
448+
449+
for i, n := range nodenames {
450+
if n == hostname {
451+
return i
452+
}
453+
}
454+
455+
return -1
456+
}
457+
458+
func DoTest() int {
459+
return getClientIndex()
460+
}
461+
396462
// Update the current list of hosts for the given resolver
397463
func (b *JSONGateResolverBuilder) update(r *JSONGateResolver) error {
398464
log.V(100).Infof("resolving target %s to %d connections\n", r.target.URL.String(), *numConnections)

go/vt/vtgateproxy/rotor_json.go

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package vtgateproxy
2+
3+
type RotorJson struct {
4+
VersionInfo string `json:"version_info"`
5+
Resources []Resource `json:"resources"`
6+
TypeURL string `json:"type_url"`
7+
ControlPlane ControlPlane `json:"control_plane"`
8+
}
9+
10+
type ControlPlane struct {
11+
Identifier string `json:"identifier"`
12+
}
13+
14+
type Resource struct {
15+
Type string `json:"@type"`
16+
ClusterName string `json:"cluster_name"`
17+
Endpoints []EndpointElement `json:"endpoints"`
18+
}
19+
20+
type EndpointElement struct {
21+
LBEndpoints []LBEndpoint `json:"lb_endpoints"`
22+
}
23+
24+
type LBEndpoint struct {
25+
Endpoint LBEndpointEndpoint `json:"endpoint"`
26+
HealthStatus HealthStatus `json:"health_status"`
27+
Metadata Metadata `json:"metadata"`
28+
}
29+
30+
type LBEndpointEndpoint struct {
31+
Address Address `json:"address"`
32+
}
33+
34+
type Address struct {
35+
SocketAddress SocketAddress `json:"socket_address"`
36+
}
37+
38+
type SocketAddress struct {
39+
Address string `json:"address"`
40+
PortValue int64 `json:"port_value"`
41+
}
42+
43+
type Metadata struct {
44+
FilterMetadata FilterMetadata `json:"filter_metadata"`
45+
}
46+
47+
type FilterMetadata struct {
48+
EnvoyLB EnvoyLB `json:"envoy.lb"`
49+
}
50+
51+
type EnvoyLB struct {
52+
Consul Consul `json:"consul"`
53+
NodeAddress string `json:"node-address"`
54+
NodeHealth NodeHealth `json:"node-health"`
55+
NodeID string `json:"node-id"`
56+
NodeName string `json:"node-name"`
57+
NodeASG ASG `json:"node:asg"`
58+
NodeAz NodeAz `json:"node:az"`
59+
NodeAzID AzID `json:"node:az_id"`
60+
NodeConsulNetworkSegment string `json:"node:consul-network-segment"`
61+
NodeConsulVersion ConsulVersion `json:"node:consul-version"`
62+
NodeEnv Env `json:"node:env"`
63+
NodeLSBRelease string `json:"node:lsb_release"`
64+
NodeNebulaAddress string `json:"node:nebula_address"`
65+
NodeOmniServiceID string `json:"node:omni_service_id"`
66+
NodePlatform Platform `json:"node:platform"`
67+
NodeProvider Provider `json:"node:provider"`
68+
NodeRegion Region `json:"node:region"`
69+
NodeRole Role `json:"node:role"`
70+
TagDatacenter TagDatacenterEnum `json:"tag:datacenter"`
71+
TagLegacyDc TagDatacenterEnum `json:"tag:legacy_dc"`
72+
}
73+
74+
type Consul struct {
75+
NodeMeta NodeMeta `json:"nodeMeta"`
76+
Tag Tag `json:"tag"`
77+
}
78+
79+
type NodeMeta struct {
80+
ASG ASG `json:"asg"`
81+
Az NodeAz `json:"az"`
82+
AzID AzID `json:"az_id"`
83+
ConsulNetworkSegment string `json:"consul-network-segment"`
84+
ConsulVersion ConsulVersion `json:"consul-version"`
85+
Env Env `json:"env"`
86+
LSBRelease string `json:"lsb_release"`
87+
NebulaAddress string `json:"nebula_address"`
88+
OmniServiceID string `json:"omni_service_id"`
89+
Platform Platform `json:"platform"`
90+
Provider Provider `json:"provider"`
91+
Region Region `json:"region"`
92+
Role Role `json:"role"`
93+
}
94+
95+
type Tag struct {
96+
DatacenterDevUsEast1 string `json:"datacenter:dev-us-east-1"`
97+
LegacyDcDevUsEast1 string `json:"legacy_dc:dev-us-east-1"`
98+
}
99+
100+
type HealthStatus string
101+
102+
const (
103+
Healthy HealthStatus = "HEALTHY"
104+
)
105+
106+
type ASG string
107+
108+
const (
109+
ASGRdevCanvasWebapp ASG = "rdev-canvas-webapp"
110+
DevContainersPoolLargeWhitecastle ASG = "dev-containers-pool-large-whitecastle"
111+
DevContainersPoolTestWhitecastle ASG = "dev-containers-pool-test-whitecastle"
112+
DevContainersPoolWhitecastle ASG = "dev-containers-pool-whitecastle"
113+
Empty ASG = ""
114+
QAEnvContainerPoolWc ASG = "qa-env-container-pool-wc"
115+
QAEnvSandboxContainerPoolWc ASG = "qa-env-sandbox-container-pool-wc"
116+
)
117+
118+
type NodeAz string
119+
120+
const (
121+
UsEast1A NodeAz = "us-east-1a"
122+
UsEast1B NodeAz = "us-east-1b"
123+
UsEast1C NodeAz = "us-east-1c"
124+
UsEast1D NodeAz = "us-east-1d"
125+
)
126+
127+
type AzID string
128+
129+
const (
130+
Use1Az1 AzID = "use1-az1"
131+
Use1Az2 AzID = "use1-az2"
132+
Use1Az4 AzID = "use1-az4"
133+
Use1Az6 AzID = "use1-az6"
134+
)
135+
136+
type ConsulVersion string
137+
138+
const (
139+
The1201Slack16 ConsulVersion = "1.20.1+slack.16"
140+
)
141+
142+
type Env string
143+
144+
const (
145+
Dev Env = "dev"
146+
)
147+
148+
type Platform string
149+
150+
const (
151+
Chef Platform = "chef"
152+
)
153+
154+
type Provider string
155+
156+
const (
157+
Ec2 Provider = "ec2"
158+
)
159+
160+
type Region string
161+
162+
const (
163+
UsEast1 Region = "us-east-1"
164+
)
165+
166+
type Role string
167+
168+
const (
169+
RoleRdevCanvasWebapp Role = "rdev-canvas-webapp"
170+
SlackDevContainer Role = "slack-dev-container"
171+
SlackQAEnvContainer Role = "slack-qa-env-container"
172+
SlackQAEnvSandboxContainer Role = "slack-qa-env-sandbox-container"
173+
)
174+
175+
type NodeHealth string
176+
177+
const (
178+
Passing NodeHealth = "passing"
179+
)
180+
181+
type TagDatacenterEnum string
182+
183+
const (
184+
DevUsEast1 TagDatacenterEnum = "dev-us-east-1"
185+
)

0 commit comments

Comments
 (0)