Skip to content

Commit 2b452fb

Browse files
bozarog7r
authored andcommitted
Make rescanSRVInterval configurable
1 parent 9ea6d8e commit 2b452fb

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

mongo/options/clientoptions.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ type ClientOptions struct {
231231
ServerSelectionTimeout *time.Duration
232232
SRVMaxHosts *int
233233
SRVServiceName *string
234+
RescanSRVInterval *time.Duration
234235
Timeout *time.Duration
235236
TLSConfig *tls.Config
236237
WriteConcern *writeconcern.WriteConcern
@@ -999,6 +1000,12 @@ func (c *ClientOptions) SetSRVServiceName(srvName string) *ClientOptions {
9991000
return c
10001001
}
10011002

1003+
// SetRescanSRVInterval specifies a custom interval between SRV hosts rescan.
1004+
func (c *ClientOptions) SetRescanSRVInterval(rescanSRVInterval time.Duration) *ClientOptions {
1005+
c.RescanSRVInterval = &rescanSRVInterval
1006+
return c
1007+
}
1008+
10021009
// MergeClientOptions combines the given *ClientOptions into a single *ClientOptions in a last one wins fashion.
10031010
// The specified options are merged with the existing options on the client, with the specified options taking
10041011
// precedence.
@@ -1109,6 +1116,9 @@ func MergeClientOptions(opts ...*ClientOptions) *ClientOptions {
11091116
if opt.SRVServiceName != nil {
11101117
c.SRVServiceName = opt.SRVServiceName
11111118
}
1119+
if opt.RescanSRVInterval != nil {
1120+
c.RescanSRVInterval = opt.RescanSRVInterval
1121+
}
11121122
if opt.Timeout != nil {
11131123
c.Timeout = opt.Timeout
11141124
}

x/mongo/driver/topology/polling_srv_records_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,12 @@ func testPollingSRVRecordsSpec(t *testing.T, uri string) {
143143
t.Run(tt.name, func(t *testing.T) {
144144
cfg, err := NewConfig(options.Client().ApplyURI(uri), nil)
145145
require.NoError(t, err, "error constructing topology configs: %v", err)
146+
cfg.RescanSRVInterval = time.Millisecond * 5
146147

147148
topo, err := New(cfg)
148149
require.NoError(t, err, "Could not create the topology: %v", err)
149150
mockRes := newMockResolver(tt.recordsToAdd, tt.recordsToRemove, tt.lookupFail, tt.lookupTimeout)
150151
topo.dnsResolver = &dns.Resolver{mockRes.LookupSRV, mockRes.LookupTXT}
151-
topo.rescanSRVInterval = time.Millisecond * 5
152152
err = topo.Connect()
153153
require.NoError(t, err, "Could not Connect to the topology: %v", err)
154154

@@ -172,12 +172,12 @@ func TestPollSRVRecords(t *testing.T) {
172172
uri := "mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100"
173173
cfg, err := NewConfig(options.Client().ApplyURI(uri), nil)
174174
require.NoError(t, err, "error constructing topology config: %v", err)
175+
cfg.RescanSRVInterval = time.Millisecond * 5
175176

176177
topo, err := New(cfg)
177178
require.NoError(t, err, "Could not create the topology: %v", err)
178179
mockRes := newMockResolver(nil, nil, false, false)
179180
topo.dnsResolver = &dns.Resolver{mockRes.LookupSRV, mockRes.LookupTXT}
180-
topo.rescanSRVInterval = time.Millisecond * 5
181181
err = topo.Connect()
182182
require.NoError(t, err, "Could not Connect to the topology: %v", err)
183183
topo.serversLock.Lock()
@@ -214,12 +214,12 @@ func TestPollSRVRecords(t *testing.T) {
214214
uri := "mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100"
215215
cfg, err := NewConfig(options.Client().ApplyURI(uri), nil)
216216
require.NoError(t, err, "error constructing topology config: %v", err)
217+
cfg.RescanSRVInterval = time.Millisecond * 5
217218

218219
topo, err := New(cfg)
219220
require.NoError(t, err, "Could not create the topology: %v", err)
220221
mockRes := newMockResolver([]*net.SRV{{"blah.bleh", 27019, 0, 0}, {"localhost.test.build.10gen.cc.", 27020, 0, 0}}, nil, false, false)
221222
topo.dnsResolver = &dns.Resolver{mockRes.LookupSRV, mockRes.LookupTXT}
222-
topo.rescanSRVInterval = time.Millisecond * 5
223223
err = topo.Connect()
224224
require.NoError(t, err, "Could not Connect to the topology: %v", err)
225225

@@ -241,13 +241,13 @@ func TestPollSRVRecords(t *testing.T) {
241241
uri := "mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100"
242242
cfg, err := NewConfig(options.Client().ApplyURI(uri), nil)
243243
require.NoError(t, err, "error constructing topology config: %v", err)
244+
cfg.RescanSRVInterval = time.Millisecond * 5
244245

245246
topo, err := New(cfg)
246247
require.NoError(t, err, "Could not create the topology: %v", err)
247248
mockRes := newMockResolver(nil, nil, false, false)
248249
mockRes.fail = 1
249250
topo.dnsResolver = &dns.Resolver{mockRes.LookupSRV, mockRes.LookupTXT}
250-
topo.rescanSRVInterval = time.Millisecond * 5
251251
err = topo.Connect()
252252
require.NoError(t, err, "Could not Connect to the topology: %v", err)
253253

@@ -272,6 +272,7 @@ func TestPollingSRVRecordsLoadBalanced(t *testing.T) {
272272

273273
cfg, err := NewConfig(options.Client().ApplyURI(uri).SetLoadBalanced(true), nil)
274274
require.NoError(t, err, "error constructing topology config: %v", err)
275+
cfg.RescanSRVInterval = time.Millisecond * 5
275276

276277
topo, err := New(cfg)
277278
require.NoError(t, err, "Could not create the topology: %v", err)
@@ -294,7 +295,6 @@ func TestPollingSRVRecordsLoadBalanced(t *testing.T) {
294295

295296
topo := createLBTopology(t, "mongodb+srv://test3.test.build.10gen.cc")
296297
topo.dnsResolver = dnsResolver
297-
topo.rescanSRVInterval = time.Millisecond * 5
298298
err := topo.Connect()
299299
assert.Nil(t, err, "Connect error: %v", err)
300300
defer func() {
@@ -303,7 +303,7 @@ func TestPollingSRVRecordsLoadBalanced(t *testing.T) {
303303

304304
// Wait for 2*rescanInterval and assert that polling was not done and the final host list only contains the
305305
// original host.
306-
time.Sleep(2 * topo.rescanSRVInterval)
306+
time.Sleep(2 * topo.cfg.RescanSRVInterval)
307307
lookupCalledTimes := atomic.LoadInt32(&mockResolver.ranLookup)
308308
assert.Equal(t, int32(0), lookupCalledTimes, "expected SRV lookup to occur 0 times, got %d", lookupCalledTimes)
309309
expectedHosts := []string{"localhost.test.build.10gen.cc:27017"}
@@ -320,13 +320,13 @@ func TestPollSRVRecordsMaxHosts(t *testing.T) {
320320
uri := "mongodb+srv://test1.test.build.10gen.cc/?heartbeatFrequencyMS=100"
321321
cfg, err := NewConfig(options.Client().ApplyURI(uri).SetSRVMaxHosts(srvMaxHosts), nil)
322322
require.NoError(t, err, "error constructing topology config: %v", err)
323+
cfg.RescanSRVInterval = time.Millisecond * 5
323324

324325
topo, err := New(cfg)
325326
require.NoError(t, err, "Could not create the topology: %v", err)
326327

327328
mockRes := newMockResolver(recordsToAdd, recordsToRemove, false, false)
328329
topo.dnsResolver = &dns.Resolver{mockRes.LookupSRV, mockRes.LookupTXT}
329-
topo.rescanSRVInterval = time.Millisecond * 5
330330
err = topo.Connect()
331331
assert.Nil(t, err, "Connect error: %v", err)
332332

@@ -392,13 +392,13 @@ func TestPollSRVRecordsServiceName(t *testing.T) {
392392
uri := "mongodb+srv://test22.test.build.10gen.cc/?heartbeatFrequencyMS=100&srvServiceName=customname"
393393
cfg, err := NewConfig(options.Client().ApplyURI(uri).SetSRVServiceName(srvServiceName), nil)
394394
require.NoError(t, err, "error constructing topology config: %v", err)
395+
cfg.RescanSRVInterval = time.Millisecond * 5
395396

396397
topo, err := New(cfg)
397398
require.NoError(t, err, "Could not create the topology: %v", err)
398399

399400
mockRes := newMockResolver(recordsToAdd, recordsToRemove, false, false)
400401
topo.dnsResolver = &dns.Resolver{mockRes.LookupSRV, mockRes.LookupTXT}
401-
topo.rescanSRVInterval = time.Millisecond * 5
402402
err = topo.Connect()
403403
assert.Nil(t, err, "Connect error: %v", err)
404404

x/mongo/driver/topology/topology.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ type Topology struct {
9393
pollingRequired bool
9494
pollingDone chan struct{}
9595
pollingwg sync.WaitGroup
96-
rescanSRVInterval time.Duration
9796
pollHeartbeatTime atomic.Value // holds a bool
9897

9998
hosts []string
@@ -148,15 +147,14 @@ func New(cfg *Config) (*Topology, error) {
148147
}
149148

150149
t := &Topology{
151-
cfg: cfg,
152-
done: make(chan struct{}),
153-
pollingDone: make(chan struct{}),
154-
rescanSRVInterval: 60 * time.Second,
155-
fsm: newFSM(),
156-
subscribers: make(map[uint64]chan description.Topology),
157-
servers: make(map[address.Address]*Server),
158-
dnsResolver: dns.DefaultResolver,
159-
id: primitive.NewObjectID(),
150+
cfg: cfg,
151+
done: make(chan struct{}),
152+
pollingDone: make(chan struct{}),
153+
fsm: newFSM(),
154+
subscribers: make(map[uint64]chan description.Topology),
155+
servers: make(map[address.Address]*Server),
156+
dnsResolver: dns.DefaultResolver,
157+
id: primitive.NewObjectID(),
160158
}
161159
t.desc.Store(description.Topology{})
162160
t.updateCallback = func(desc description.Server) description.Server {
@@ -801,7 +799,7 @@ func (t *Topology) pollSRVRecords(hosts string) {
801799
serverConfig := newServerConfig(t.cfg.ServerOpts...)
802800
heartbeatInterval := serverConfig.heartbeatInterval
803801

804-
pollTicker := time.NewTicker(t.rescanSRVInterval)
802+
pollTicker := time.NewTicker(t.cfg.RescanSRVInterval)
805803
defer pollTicker.Stop()
806804
t.pollHeartbeatTime.Store(false)
807805
var doneOnce bool
@@ -835,7 +833,7 @@ func (t *Topology) pollSRVRecords(hosts string) {
835833
}
836834
if t.pollHeartbeatTime.Load().(bool) {
837835
pollTicker.Stop()
838-
pollTicker = time.NewTicker(t.rescanSRVInterval)
836+
pollTicker = time.NewTicker(t.cfg.RescanSRVInterval)
839837
t.pollHeartbeatTime.Store(false)
840838
}
841839

x/mongo/driver/topology/topology_options.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
)
2626

2727
const defaultServerSelectionTimeout = 30 * time.Second
28+
const defaultRescanSRVInterval = 60 * time.Second
2829

2930
// Config is used to construct a topology.
3031
type Config struct {
@@ -39,6 +40,7 @@ type Config struct {
3940
SRVServiceName string
4041
LoadBalanced bool
4142
logger *logger.Logger
43+
RescanSRVInterval time.Duration
4244
}
4345

4446
// ConvertToDriverAPIOptions converts a options.ServerAPIOptions instance to a driver.ServerAPIOptions.
@@ -88,6 +90,8 @@ func NewConfig(co *options.ClientOptions, clock *session.ClusterClock) (*Config,
8890
// Set the default "ServerSelectionTimeout" to 30 seconds.
8991
cfgp.ServerSelectionTimeout = defaultServerSelectionTimeout
9092

93+
cfgp.RescanSRVInterval = defaultRescanSRVInterval
94+
9195
// Set the default "SeedList" to localhost.
9296
cfgp.SeedList = []string{"localhost:27017"}
9397

@@ -108,6 +112,10 @@ func NewConfig(co *options.ClientOptions, clock *session.ClusterClock) (*Config,
108112
cfgp.SRVServiceName = *co.SRVServiceName
109113
}
110114

115+
if co.RescanSRVInterval != nil {
116+
cfgp.RescanSRVInterval = *co.RescanSRVInterval
117+
}
118+
111119
if co.SRVMaxHosts != nil {
112120
cfgp.SRVMaxHosts = *co.SRVMaxHosts
113121
}

0 commit comments

Comments
 (0)