@@ -84,6 +84,7 @@ type JSONGateResolverBuilder struct {
84
84
affinityField string
85
85
affinityValue string
86
86
numConnections int
87
+ numBackupConns int
87
88
88
89
mu sync.RWMutex
89
90
targets map [string ][]targetHost
@@ -115,6 +116,7 @@ func RegisterJSONGateResolver(
115
116
affinityField string ,
116
117
affinityValue string ,
117
118
numConnections int ,
119
+ numBackupConns int ,
118
120
) (* JSONGateResolverBuilder , error ) {
119
121
jsonDiscovery := & JSONGateResolverBuilder {
120
122
targets : map [string ][]targetHost {},
@@ -125,6 +127,7 @@ func RegisterJSONGateResolver(
125
127
affinityField : affinityField ,
126
128
affinityValue : affinityValue ,
127
129
numConnections : numConnections ,
130
+ numBackupConns : numBackupConns ,
128
131
sorter : newShuffleSorter (),
129
132
}
130
133
@@ -265,7 +268,7 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
265
268
return false , fmt .Errorf ("error parsing JSON discovery file %s: %v" , b .jsonPath , err )
266
269
}
267
270
268
- var targets = map [string ][]targetHost {}
271
+ var allTargets = map [string ][]targetHost {}
269
272
for _ , host := range hosts {
270
273
hostname , hasHostname := host ["host" ]
271
274
address , hasAddress := host [b .addressField ]
@@ -312,7 +315,7 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
312
315
}
313
316
314
317
target := targetHost {hostname .(string ), fmt .Sprintf ("%s:%s" , address , port ), poolType .(string ), affinity .(string ), affinity == b .affinityValue }
315
- targets [target .PoolType ] = append (targets [target .PoolType ], target )
318
+ allTargets [target .PoolType ] = append (allTargets [target .PoolType ], target )
316
319
}
317
320
318
321
// If a pool disappears, the metric will not record this unless all counts
@@ -322,16 +325,25 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
322
325
// targets and only resetting pools which disappear.
323
326
targetCount .ResetAll ()
324
327
325
- for poolType := range targets {
326
- b .sorter .shuffleSort (targets [poolType ])
327
- if len (targets [poolType ]) > * numConnections {
328
- targets [poolType ] = targets [poolType ][:b .numConnections ]
328
+ var selected = map [string ][]targetHost {}
329
+
330
+ for poolType := range allTargets {
331
+ b .sorter .shuffleSort (allTargets [poolType ])
332
+
333
+ // try to pick numConnections from the front of the list (local zone) and numBackupConnections
334
+ // from the tail (remote zone). if that's not possible, just take the whole set
335
+ if len (allTargets [poolType ]) >= b .numConnections + b .numBackupConns {
336
+ remoteOffset := len (allTargets [poolType ]) - b .numBackupConns
337
+ selected [poolType ] = append (allTargets [poolType ][:b .numConnections ], allTargets [poolType ][remoteOffset :]... )
338
+ } else {
339
+ selected [poolType ] = allTargets [poolType ]
329
340
}
330
- targetCount .Set (poolType , int64 (len (targets [poolType ])))
341
+
342
+ targetCount .Set (poolType , int64 (len (selected [poolType ])))
331
343
}
332
344
333
345
b .mu .Lock ()
334
- b .targets = targets
346
+ b .targets = selected
335
347
b .mu .Unlock ()
336
348
337
349
return true , nil
0 commit comments