Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GODRIVER-2222 Prevent removing valid servers when updating SRV hosts. #805

Merged
merged 2 commits into from Nov 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 5 additions & 9 deletions x/mongo/driver/connstring/connstring.go
Expand Up @@ -306,15 +306,11 @@ func (p *parser) parse(original string) error {
}

// If p.SRVMaxHosts is non-zero and is less than the number of hosts, randomly
// select SRVMaxHosts hosts from parsedHosts using the modern Fisher-Yates
// algorithm.
if p.SRVMaxHosts != 0 && p.SRVMaxHosts < len(parsedHosts) {
// TODO(GODRIVER-1876): Use rand#Shuffle after dropping Go 1.9 support.
n := len(parsedHosts)
for i := 0; i < n-1; i++ {
j := i + random.Intn(n-i)
parsedHosts[j], parsedHosts[i] = parsedHosts[i], parsedHosts[j]
}
// select SRVMaxHosts hosts from parsedHosts.
if p.SRVMaxHosts > 0 && p.SRVMaxHosts < len(parsedHosts) {
random.Shuffle(len(parsedHosts), func(i, j int) {
parsedHosts[i], parsedHosts[j] = parsedHosts[j], parsedHosts[i]
})
parsedHosts = parsedHosts[:p.SRVMaxHosts]
}
}
Expand Down
3 changes: 0 additions & 3 deletions x/mongo/driver/topology/polling_srv_records_test.go
Expand Up @@ -371,9 +371,6 @@ func TestPollSRVRecordsMaxHosts(t *testing.T) {
compareHosts(t, actualHosts, expectedHosts)
})
t.Run("SRVMaxHosts is less than number of hosts", func(t *testing.T) {
// TODO: Enable with GODRIVER-2222.
t.Skipf("TODO: Enable with GODRIVER-2222")

recordsToAdd := []*net.SRV{{"localhost.test.build.10gen.cc.", 27019, 0, 0}, {"localhost.test.build.10gen.cc.", 27020, 0, 0}}
recordsToRemove := []*net.SRV{{"localhost.test.build.10gen.cc.", 27018, 0, 0}}
topo, disconnect := simulateSRVPoll(2, recordsToAdd, recordsToRemove)
Expand Down
24 changes: 11 additions & 13 deletions x/mongo/driver/topology/topology.go
Expand Up @@ -546,19 +546,6 @@ func (t *Topology) pollSRVRecords() {
t.pollHeartbeatTime.Store(false)
}

// If t.cfg.srvMaxHosts is non-zero and is less than the number of hosts, randomly
// select srvMaxHosts hosts from parsedHosts using the modern Fisher-Yates
// algorithm.
if t.cfg.srvMaxHosts != 0 && t.cfg.srvMaxHosts < len(parsedHosts) {
// TODO(GODRIVER-1876): Use rand#Shuffle after dropping Go 1.9 support.
n := len(parsedHosts)
for i := 0; i < n-1; i++ {
j := i + random.Intn(n-i)
parsedHosts[j], parsedHosts[i] = parsedHosts[i], parsedHosts[j]
}
parsedHosts = parsedHosts[:t.cfg.srvMaxHosts]
}

cont := t.processSRVResults(parsedHosts)
if !cont {
break
Expand Down Expand Up @@ -597,11 +584,22 @@ func (t *Topology) processSRVResults(parsedHosts []string) bool {
t.fsm.removeServerByAddr(addr)
t.publishServerClosedEvent(s.address)
}

// Now that we've removed all the hosts that disappeared from the SRV record, we need to add any
// new hosts added to the SRV record. Shuffle the list of added hosts so we add them in random
// order. Stop adding hosts whenever we reach srvMaxHosts.
random.Shuffle(len(diff.Added), func(i, j int) {
matthewdale marked this conversation as resolved.
Show resolved Hide resolved
diff.Added[i], diff.Added[j] = diff.Added[j], diff.Added[i]
})
for _, a := range diff.Added {
if t.cfg.srvMaxHosts > 0 && len(t.servers) >= t.cfg.srvMaxHosts {
break
}
addr := address.Address(a).Canonicalize()
_ = t.addServer(addr)
t.fsm.addServer(addr)
}

//store new description
newDesc := description.Topology{
Kind: t.fsm.Kind,
Expand Down