Skip to content

Commit 94b769f

Browse files
author
Divjot Arora
authored
GODRIVER-1499 Remove timeout checks from server selection fast path (#356)
1 parent 7f7a06d commit 94b769f

File tree

4 files changed

+24
-31
lines changed

4 files changed

+24
-31
lines changed

x/mongo/driver/operation.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,6 @@ func (op Operation) selectServer(ctx context.Context) (Server, error) {
195195
return nil, err
196196
}
197197

198-
select {
199-
case <-ctx.Done():
200-
return nil, ctx.Err()
201-
default:
202-
}
203-
204198
selector := op.Selector
205199
if selector == nil {
206200
rp := op.ReadPreference

x/mongo/driver/operation_test.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,6 @@ func TestOperation(t *testing.T) {
5454
t.Error("Expected a validation error from selectServer, but got <nil>")
5555
}
5656
})
57-
t.Run("returns context error when expired", func(t *testing.T) {
58-
op := &Operation{
59-
CommandFn: func([]byte, description.SelectedServer) ([]byte, error) { return nil, nil },
60-
Deployment: new(mockDeployment),
61-
Database: "testing",
62-
}
63-
ctx, cancel := context.WithCancel(context.Background())
64-
cancel()
65-
want := context.Canceled
66-
_, got := op.selectServer(ctx)
67-
if got != want {
68-
t.Errorf("Did not get expected error. got %v; want %v", got, want)
69-
}
70-
})
7157
t.Run("uses specified server selector", func(t *testing.T) {
7258
want := new(mockServerSelector)
7359
d := new(mockDeployment)

x/mongo/driver/topology/topology.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -459,13 +459,8 @@ func (t *Topology) selectServerFromSubscription(ctx context.Context, subscriptio
459459
func (t *Topology) selectServerFromDescription(ctx context.Context, desc description.Topology,
460460
selectionState serverSelectionState) ([]description.Server, error) {
461461

462-
select {
463-
case <-ctx.Done():
464-
return nil, ctx.Err()
465-
case <-selectionState.timeoutChan:
466-
return nil, wrapServerSelectionError(ErrServerSelectionTimeout, t)
467-
default:
468-
}
462+
// Unlike selectServerFromSubscription, this code path does not check ctx.Done or selectionState.timeoutChan because
463+
// selecting a server from a description is not a blocking operation.
469464

470465
var allowed []description.Server
471466
for _, s := range desc.Servers {

x/mongo/driver/topology/topology_test.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,8 @@ func TestServerSelection(t *testing.T) {
315315
t.Errorf("Incorrect sever selected. got %s; want %s", srvs[0].Addr, desc.Servers[1].Addr)
316316
}
317317
})
318-
t.Run("no subscription in fast path", func(t *testing.T) {
319-
// assert that a subscription is not created if there is a server available
318+
t.Run("fast path does not subscribe or check timeouts", func(t *testing.T) {
319+
// Assert that the server selection fast path does not create a Subscription or check for timeout errors.
320320
topo, err := New()
321321
noerr(t, err)
322322
topo.cfg.cs.HeartbeatInterval = time.Minute
@@ -335,13 +335,31 @@ func TestServerSelection(t *testing.T) {
335335
topo.servers[srv.Addr] = s
336336
}
337337

338-
// manually close subscriptions so calls to Subscribe will error
338+
// Manually close subscriptions so calls to Subscribe will error and pass in a cancelled context to ensure the
339+
// fast path ignores timeout errors.
339340
topo.subscriptionsClosed = true
340-
selectedServer, err := topo.SelectServer(context.Background(), description.WriteSelector())
341+
ctx, cancel := context.WithCancel(context.Background())
342+
cancel()
343+
selectedServer, err := topo.SelectServer(ctx, description.WriteSelector())
341344
noerr(t, err)
342345
selectedAddr := selectedServer.(*SelectedServer).address
343346
assert.Equal(t, primaryAddr, selectedAddr, "expected address %v, got %v", primaryAddr, selectedAddr)
344347
})
348+
t.Run("default to selecting from subscription if fast path fails", func(t *testing.T) {
349+
topo, err := New()
350+
noerr(t, err)
351+
352+
topo.cfg.cs.HeartbeatInterval = time.Minute
353+
atomic.StoreInt32(&topo.connectionstate, connected)
354+
desc := description.Topology{
355+
Servers: []description.Server{},
356+
}
357+
topo.desc.Store(desc)
358+
359+
topo.subscriptionsClosed = true
360+
_, err = topo.SelectServer(context.Background(), description.WriteSelector())
361+
assert.Equal(t, ErrSubscribeAfterClosed, err, "expected error %v, got %v", ErrSubscribeAfterClosed, err)
362+
})
345363
}
346364

347365
func TestSessionTimeout(t *testing.T) {

0 commit comments

Comments
 (0)