Skip to content

Commit a0ded67

Browse files
author
Divjot Arora
committed
Add diagnostic information to server selection errors.
GODRIVER-733 Change-Id: Ib5fe3784dbc75287b60aa89045687d7249e111ae
1 parent ceee14b commit a0ded67

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

x/mongo/driver/topology/server.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"sync/atomic"
1515
"time"
1616

17+
"fmt"
1718
"github.com/mongodb/mongo-go-driver/bson"
1819
"github.com/mongodb/mongo-go-driver/event"
1920
"github.com/mongodb/mongo-go-driver/x/bsonx"
@@ -61,6 +62,21 @@ const (
6162
connecting
6263
)
6364

65+
func connectionStateString(state int32) string {
66+
switch state {
67+
case 0:
68+
return "Disconnected"
69+
case 1:
70+
return "Disconnecting"
71+
case 2:
72+
return "Connected"
73+
case 3:
74+
return "Connecting"
75+
}
76+
77+
return ""
78+
}
79+
6480
// Server is a single server within a topology.
6581
type Server struct {
6682
cfg *serverConfig
@@ -456,6 +472,24 @@ func (s *Server) BuildLegacyCursor(ns command.Namespace, cursorID int64, batch [
456472
return newLegacyCursor(ns, cursorID, batch, limit, batchSize, s)
457473
}
458474

475+
// String implements the Stringer interface.
476+
func (s *Server) String() string {
477+
desc := s.Description()
478+
str := fmt.Sprintf("Addr: %s, Type: %s, State: %s",
479+
s.address, desc.Kind, connectionStateString(s.connectionstate))
480+
if len(desc.Tags) != 0 {
481+
str += fmt.Sprintf(", Tag sets: %s", desc.Tags)
482+
}
483+
if s.connectionstate == connected {
484+
str += fmt.Sprintf(", Avergage RTT: %d", s.averageRTT)
485+
}
486+
if desc.LastError != nil {
487+
str += fmt.Sprintf(", Last error: %s", desc.LastError)
488+
}
489+
490+
return str
491+
}
492+
459493
// ServerSubscription represents a subscription to the description.Server updates for
460494
// a specific server.
461495
type ServerSubscription struct {

x/mongo/driver/topology/topology.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"sync/atomic"
1919
"time"
2020

21+
"fmt"
2122
"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
2223
"github.com/mongodb/mongo-go-driver/x/mongo/driver/session"
2324
"github.com/mongodb/mongo-go-driver/x/network/address"
@@ -289,6 +290,10 @@ func (t *Topology) FindServer(selected description.Server) (*SelectedServer, err
289290
}, nil
290291
}
291292

293+
func wrapServerSelectionError(err error, t *Topology) error {
294+
return fmt.Errorf("server selection error: %v\ncurrent topology: %s", err, t.String())
295+
}
296+
292297
// selectServer is the core piece of server selection. It handles getting
293298
// topology descriptions and running sever selection on those descriptions.
294299
func (t *Topology) selectServer(ctx context.Context, subscriptionCh <-chan description.Topology, ss description.ServerSelector, timeoutCh <-chan time.Time) ([]description.Server, error) {
@@ -298,7 +303,7 @@ func (t *Topology) selectServer(ctx context.Context, subscriptionCh <-chan descr
298303
case <-ctx.Done():
299304
return nil, ctx.Err()
300305
case <-timeoutCh:
301-
return nil, ErrServerSelectionTimeout
306+
return nil, wrapServerSelectionError(ErrServerSelectionTimeout, t)
302307
case current = <-subscriptionCh:
303308
}
304309

@@ -311,7 +316,7 @@ func (t *Topology) selectServer(ctx context.Context, subscriptionCh <-chan descr
311316

312317
suitable, err := ss.SelectServer(current, allowed)
313318
if err != nil {
314-
return nil, err
319+
return nil, wrapServerSelectionError(err, t)
315320
}
316321

317322
if len(suitable) > 0 {
@@ -426,6 +431,16 @@ func (t *Topology) removeServer(ctx context.Context, addr address.Address, serve
426431
delete(t.servers, addr)
427432
}
428433

434+
// String implements the Stringer interface
435+
func (t *Topology) String() string {
436+
desc := t.Description()
437+
str := fmt.Sprintf("Type: %s\nServers:\n", desc.Kind)
438+
for _, s := range t.servers {
439+
str += s.String() + "\n"
440+
}
441+
return str
442+
}
443+
429444
// Subscription is a subscription to updates to the description of the Topology that created this
430445
// Subscription.
431446
type Subscription struct {

x/mongo/driver/topology/topology_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ func TestServerSelection(t *testing.T) {
172172
t.Errorf("Timed out while trying to retrieve selected servers")
173173
}
174174

175-
if err != ErrServerSelectionTimeout {
176-
t.Errorf("Incorrect error received. got %v; want %v", err, ErrServerSelectionTimeout)
175+
if err == nil {
176+
t.Fatalf("did not receive error from server selection")
177177
}
178178
})
179179
t.Run("Error", func(t *testing.T) {
@@ -201,8 +201,8 @@ func TestServerSelection(t *testing.T) {
201201
t.Errorf("Timed out while trying to retrieve selected servers")
202202
}
203203

204-
if err != errSelectionError {
205-
t.Errorf("Incorrect error received. got %v; want %v", err, errSelectionError)
204+
if err == nil {
205+
t.Fatalf("did not receive error from server selection")
206206
}
207207
})
208208
t.Run("findServer returns topology kind", func(t *testing.T) {

0 commit comments

Comments
 (0)