@@ -84,6 +84,7 @@ type JSONGateResolverBuilder struct {
8484 affinityField string
8585 affinityValue string
8686 numConnections int
87+ numBackupConns int
8788
8889 mu sync.RWMutex
8990 targets map [string ][]targetHost
@@ -115,6 +116,7 @@ func RegisterJSONGateResolver(
115116 affinityField string ,
116117 affinityValue string ,
117118 numConnections int ,
119+ numBackupConns int ,
118120) (* JSONGateResolverBuilder , error ) {
119121 jsonDiscovery := & JSONGateResolverBuilder {
120122 targets : map [string ][]targetHost {},
@@ -125,6 +127,7 @@ func RegisterJSONGateResolver(
125127 affinityField : affinityField ,
126128 affinityValue : affinityValue ,
127129 numConnections : numConnections ,
130+ numBackupConns : numBackupConns ,
128131 sorter : newShuffleSorter (),
129132 }
130133
@@ -265,7 +268,7 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
265268 return false , fmt .Errorf ("error parsing JSON discovery file %s: %v" , b .jsonPath , err )
266269 }
267270
268- var targets = map [string ][]targetHost {}
271+ var allTargets = map [string ][]targetHost {}
269272 for _ , host := range hosts {
270273 hostname , hasHostname := host ["host" ]
271274 address , hasAddress := host [b .addressField ]
@@ -312,7 +315,7 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
312315 }
313316
314317 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 )
316319 }
317320
318321 // If a pool disappears, the metric will not record this unless all counts
@@ -322,16 +325,25 @@ func (b *JSONGateResolverBuilder) parse() (bool, error) {
322325 // targets and only resetting pools which disappear.
323326 targetCount .ResetAll ()
324327
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 ]
329340 }
330- targetCount .Set (poolType , int64 (len (targets [poolType ])))
341+
342+ targetCount .Set (poolType , int64 (len (selected [poolType ])))
331343 }
332344
333345 b .mu .Lock ()
334- b .targets = targets
346+ b .targets = selected
335347 b .mu .Unlock ()
336348
337349 return true , nil
0 commit comments