Skip to content

Commit

Permalink
shuffle targets during parse phase
Browse files Browse the repository at this point in the history
  • Loading branch information
dedelala committed May 14, 2024
1 parent 4bd6fbc commit 01cfd99
Showing 1 changed file with 13 additions and 18 deletions.
31 changes: 13 additions & 18 deletions go/vt/vtgateproxy/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ type JSONGateResolverBuilder struct {
targets map[string][]targetHost
resolvers []*JSONGateResolver

rand *rand.Rand
ticker *time.Ticker
checksum []byte
}
Expand Down Expand Up @@ -133,9 +132,6 @@ func (*JSONGateResolverBuilder) Scheme() string { return "vtgate" }

// Parse and validate the format of the file and start watching for changes
func (b *JSONGateResolverBuilder) start() error {

b.rand = rand.New(rand.NewSource(time.Now().UnixNano()))

// Perform the initial parse
_, err := b.parse()
if err != nil {
Expand Down Expand Up @@ -288,11 +284,7 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
}

for poolType := range targets {
if b.affinityField != "" {
sort.Slice(targets[poolType], func(i, j int) bool {
return b.affinityValue == targets[poolType][i].Affinity
})
}
shuffleSort(targets[poolType], b.affinityField, b.affinityValue)
if len(targets[poolType]) > *numConnections {
targets[poolType] = targets[poolType][:*numConnections]
}
Expand Down Expand Up @@ -324,27 +316,30 @@ func (b *JSONGateResolverBuilder) GetTargets(poolType string) []targetHost {
targets = append(targets, b.targets[poolType]...)
b.mu.RUnlock()

// Shuffle to ensure every host has a different order to iterate through, putting
// the affinity matching (e.g. same az) hosts at the front and the non-matching ones
// at the end.
//
// Only need to do n-1 swaps since the last host is always in the right place.
shuffleSort(targets, b.affinityField, b.affinityValue)

return targets
}

// shuffleSort shuffles a slice of targetHost to ensure every host has a
// different order to iterate through, putting the affinity matching (e.g. same
// az) hosts at the front and the non-matching ones at the end.
func shuffleSort(targets []targetHost, affinityField, affinityValue string) {
n := len(targets)
head := 0
// Only need to do n-1 swaps since the last host is always in the right place.
tail := n - 1
for i := 0; i < n-1; i++ {
j := head + b.rand.Intn(tail-head+1)
j := head + rand.Intn(tail-head+1)

if *affinityField != "" && *affinityValue == targets[j].Affinity {
if affinityField != "" && affinityValue == targets[j].Affinity {
targets[head], targets[j] = targets[j], targets[head]
head++
} else {
targets[tail], targets[j] = targets[j], targets[tail]
tail--
}
}

return targets
}

// Update the current list of hosts for the given resolver
Expand Down

0 comments on commit 01cfd99

Please sign in to comment.