Skip to content

Commit

Permalink
GODRIVER-1849 Add new WaitQueueTimeoutError to wrap context error (#568)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjirewis committed Feb 1, 2021
1 parent a058925 commit b047752
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
2 changes: 1 addition & 1 deletion x/mongo/driver/topology/CMAP_spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func runCMAPTest(t *testing.T, testFileName string) {
for len(testInfo.backgroundThreadErrors) > 0 {
bgErr := <-testInfo.backgroundThreadErrors
errs = append(errs, bgErr)
if bgErr != nil && strings.ToLower(test.Error.Message) == bgErr.Error() {
if bgErr != nil && strings.Contains(bgErr.Error(), strings.ToLower(test.Error.Message)) {
erroredCorrectly = true
break
}
Expand Down
21 changes: 20 additions & 1 deletion x/mongo/driver/topology/errors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package topology

import "fmt"
import (
"fmt"
)

// ConnectionError represents a connection error.
type ConnectionError struct {
Expand All @@ -25,3 +27,20 @@ func (e ConnectionError) Error() string {
func (e ConnectionError) Unwrap() error {
return e.Wrapped
}

// WaitQueueTimeoutError represents a timeout when requesting a connection from the pool
type WaitQueueTimeoutError struct {
Wrapped error
}

func (w WaitQueueTimeoutError) Error() string {
errorMsg := "timed out while checking out a connection from connection pool"
if w.Wrapped != nil {
return fmt.Sprintf("%s: %s", errorMsg, w.Wrapped.Error())
}
return errorMsg
}

func (w WaitQueueTimeoutError) Unwrap() error {
return w.Wrapped
}
8 changes: 4 additions & 4 deletions x/mongo/driver/topology/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ var ErrConnectionClosed = ConnectionError{ConnectionID: "<closed>", message: "co
// ErrWrongPool is return when a connection is returned to a pool it doesn't belong to.
var ErrWrongPool = PoolError("connection does not belong to this pool")

// ErrWaitQueueTimeout is returned when the request to get a connection from the pool timesout when on the wait queue
var ErrWaitQueueTimeout = PoolError("timed out while checking out a connection from connection pool")

// PoolError is an error returned from a Pool method.
type PoolError string

Expand Down Expand Up @@ -340,7 +337,10 @@ func (p *pool) get(ctx context.Context) (*connection, error) {
Reason: event.ReasonTimedOut,
})
}
return nil, ErrWaitQueueTimeout
errWaitQueueTimeout := WaitQueueTimeoutError{
Wrapped: ctx.Err(),
}
return nil, errWaitQueueTimeout
}

// This loop is so that we don't end up with more than maxPoolSize connections if p.conns.Maintain runs between
Expand Down
34 changes: 34 additions & 0 deletions x/mongo/driver/topology/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,40 @@ func TestPool(t *testing.T) {
noerr(t, err)
})
})
t.Run("wait queue timeout error", func(t *testing.T) {
cleanup := make(chan struct{})
addr := bootstrapConnections(t, 1, func(nc net.Conn) {
<-cleanup
_ = nc.Close()
})
d := newdialer(&net.Dialer{})
pc := poolConfig{
Address: address.Address(addr.String()),
MaxPoolSize: 1,
}
p, err := newPool(pc, WithDialer(func(Dialer) Dialer { return d }))
noerr(t, err)
err = p.connect()
noerr(t, err)

// get first connection.
_, err = p.get(context.Background())
noerr(t, err)

// Set a short timeout and get again.
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)
defer cancel()
_, err = p.get(ctx)
assert.NotNil(t, err, "expected a WaitQueueTimeout; got nil")

// Assert that error received is WaitQueueTimeoutError with context deadline exceeded.
wqtErr, ok := err.(WaitQueueTimeoutError)
assert.True(t, ok, "expected a WaitQueueTimeoutError; got %v", err)
assert.True(t, wqtErr.Unwrap() == context.DeadlineExceeded,
"expected a timeout error; got %v", wqtErr)

close(cleanup)
})
}

type sleepDialer struct {
Expand Down

0 comments on commit b047752

Please sign in to comment.