Skip to content

Commit a452f51

Browse files
authored
GODRIVER-2222 Prevent removing valid servers when updating SRV hosts. (#805)
1 parent 13af40d commit a452f51

File tree

3 files changed

+19
-25
lines changed

3 files changed

+19
-25
lines changed

x/mongo/driver/connstring/connstring.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,15 +307,11 @@ func (p *parser) parse(original string) error {
307307
}
308308

309309
// If p.SRVMaxHosts is non-zero and is less than the number of hosts, randomly
310-
// select SRVMaxHosts hosts from parsedHosts using the modern Fisher-Yates
311-
// algorithm.
312-
if p.SRVMaxHosts != 0 && p.SRVMaxHosts < len(parsedHosts) {
313-
// TODO(GODRIVER-1876): Use rand#Shuffle after dropping Go 1.9 support.
314-
n := len(parsedHosts)
315-
for i := 0; i < n-1; i++ {
316-
j := i + random.Intn(n-i)
317-
parsedHosts[j], parsedHosts[i] = parsedHosts[i], parsedHosts[j]
318-
}
310+
// select SRVMaxHosts hosts from parsedHosts.
311+
if p.SRVMaxHosts > 0 && p.SRVMaxHosts < len(parsedHosts) {
312+
random.Shuffle(len(parsedHosts), func(i, j int) {
313+
parsedHosts[i], parsedHosts[j] = parsedHosts[j], parsedHosts[i]
314+
})
319315
parsedHosts = parsedHosts[:p.SRVMaxHosts]
320316
}
321317
}

x/mongo/driver/topology/polling_srv_records_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,6 @@ func TestPollSRVRecordsMaxHosts(t *testing.T) {
371371
compareHosts(t, actualHosts, expectedHosts)
372372
})
373373
t.Run("SRVMaxHosts is less than number of hosts", func(t *testing.T) {
374-
// TODO: Enable with GODRIVER-2222.
375-
t.Skipf("TODO: Enable with GODRIVER-2222")
376-
377374
recordsToAdd := []*net.SRV{{"localhost.test.build.10gen.cc.", 27019, 0, 0}, {"localhost.test.build.10gen.cc.", 27020, 0, 0}}
378375
recordsToRemove := []*net.SRV{{"localhost.test.build.10gen.cc.", 27018, 0, 0}}
379376
topo, disconnect := simulateSRVPoll(2, recordsToAdd, recordsToRemove)

x/mongo/driver/topology/topology.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -547,19 +547,6 @@ func (t *Topology) pollSRVRecords() {
547547
t.pollHeartbeatTime.Store(false)
548548
}
549549

550-
// If t.cfg.srvMaxHosts is non-zero and is less than the number of hosts, randomly
551-
// select srvMaxHosts hosts from parsedHosts using the modern Fisher-Yates
552-
// algorithm.
553-
if t.cfg.srvMaxHosts != 0 && t.cfg.srvMaxHosts < len(parsedHosts) {
554-
// TODO(GODRIVER-1876): Use rand#Shuffle after dropping Go 1.9 support.
555-
n := len(parsedHosts)
556-
for i := 0; i < n-1; i++ {
557-
j := i + random.Intn(n-i)
558-
parsedHosts[j], parsedHosts[i] = parsedHosts[i], parsedHosts[j]
559-
}
560-
parsedHosts = parsedHosts[:t.cfg.srvMaxHosts]
561-
}
562-
563550
cont := t.processSRVResults(parsedHosts)
564551
if !cont {
565552
break
@@ -598,11 +585,25 @@ func (t *Topology) processSRVResults(parsedHosts []string) bool {
598585
t.fsm.removeServerByAddr(addr)
599586
t.publishServerClosedEvent(s.address)
600587
}
588+
589+
// Now that we've removed all the hosts that disappeared from the SRV record, we need to add any
590+
// new hosts added to the SRV record. If adding all of the new hosts would increase the number
591+
// of servers past srvMaxHosts, shuffle the list of added hosts.
592+
if t.cfg.srvMaxHosts > 0 && len(t.servers)+len(diff.Added) > t.cfg.srvMaxHosts {
593+
random.Shuffle(len(diff.Added), func(i, j int) {
594+
diff.Added[i], diff.Added[j] = diff.Added[j], diff.Added[i]
595+
})
596+
}
597+
// Add all added hosts until the number of servers reaches srvMaxHosts.
601598
for _, a := range diff.Added {
599+
if t.cfg.srvMaxHosts > 0 && len(t.servers) >= t.cfg.srvMaxHosts {
600+
break
601+
}
602602
addr := address.Address(a).Canonicalize()
603603
_ = t.addServer(addr)
604604
t.fsm.addServer(addr)
605605
}
606+
606607
//store new description
607608
newDesc := description.Topology{
608609
Kind: t.fsm.Kind,

0 commit comments

Comments
 (0)