-
Notifications
You must be signed in to change notification settings - Fork 893
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-1925 Surface cursor errors in DownloadStream fillBuffer #653
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! though as a nit, I don't feel like a lot of the comments in gridfs_test.go are necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also close ds.cursor
in DownloadStream#Close
? If a user creates a DownloadStream
and then closes it before fully reading the file, we should close the cursor to prevent cursor/session leaks in the application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed some extraneous comments from the gridfs test and Close
d the underlying cursor in DownloadStream#Close()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with an extra test case for Skip
!
@@ -119,6 +119,9 @@ func (ds *DownloadStream) Close() error { | |||
} | |||
|
|||
ds.closed = true | |||
if ds.cursor != nil { | |||
return ds.cursor.Close(context.Background()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to change. I was initially slightly concerned. This adds blocking work with context.Background()
, which could block indefinitely. But previously this would always return immediately.
Though, if the cursor is exhausted, this should do no work (killCursors won't be sent to the server). If the cursor is not exhausted, this still seems preferable to leaking cursors server-side in the event of an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A good point and valid concern. But, leaking cursors doesn't seem great; and on the driver side, not closing the cursor in this case will leave a session open (client.NumberSessionsInProgress() > 0
).
mongo/integration/gridfs_test.go
Outdated
@@ -369,6 +370,34 @@ func TestGridFS(x *testing.T) { | |||
_, err = bucket.OpenDownloadStream(oid) | |||
assert.Equal(mt, gridfs.ErrMissingChunkSize, err, "expected error %v, got %v", gridfs.ErrMissingChunkSize, err) | |||
}) | |||
mt.Run("cursor error during read after downloading", func(mt *mtest.T) { | |||
// To simulate a cursor error we upload a file larger than the 16MB default batch size, | |||
// so Read() will actually execute a getMore against the server. Since the ReadDeadline is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC the test itself won't send a getMore
. It should fail on the first iteration of the cursor.
// so Read() will actually execute a getMore against the server. Since the ReadDeadline is | |
// so the underlying cursor remains open on the server. Since the ReadDeadline is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah you're right. Previously I was using a failpoint
on getMore
, but the timeout error just comes from iterating the cursor. Changed.
assert.Nil(mt, err, "SetReadDeadline error: %v", err) | ||
|
||
p := make([]byte, len(fileData)) | ||
_, err = ds.Read(p) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you parameterize this test case, or add a test for Skip
as well? This reminded me about GODRIVER-1806, and how Read
and Skip
are near duplicates, but Skip
avoids extra copies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah great catch. Read
and Skip
both call fillBuffer
, where the bug in error surfacing was. Added a different test case for Skip
(wasn't sure how to parameterize given Skip
and Read
have different function signatures).
* 'master' of https://github.com/mongodb/mongo-go-driver: (39 commits) GODRIVER-2004 Add Versioned API connection examples for Docs (mongodb#665) GODRIVER-1961 Run OCSP tests against RHEL 7.0 (mongodb#664) GODRIVER-1844 finer precision for getSecondsSinceEpoch (mongodb#666) GODRIVER-1973 create internal copy of aws v4 signing code (mongodb#657) GODRIVER-1951 Update the Go version for Evergreen builds to 1.16 (mongodb#663) GODRIVER-1949 add more ignored killAllSessions errors for unified tes… (mongodb#658) GODRIVER-1963 remove dropDatabase result (mongodb#660) GODRIVER-1180 Remove legacy transform functions from mongo (mongodb#583) GODRIVER-1937 Update legacy ListCollections to support the BatchSize option for server version 2.6 (mongodb#656) GODRIVER-1933 remove xtrace from shell scripts (mongodb#661) fix README error handling of FindOne (mongodb#636) GODRIVER-1938 update mongocryptd serverSelectionTimeout to 10 seconds (mongodb#659) GODRIVER-1925 Surface cursor errors in DownloadStream fillBuffer (mongodb#653) GODRIVER-1955 create labeledError interface (mongodb#651) GODRIVER-1947 Unmarshal unicode surrogate pairs correctly in UnmarshalExtJSON. (mongodb#649) Changed order of actions in ObjectIDFromHex func (mongodb#637) GODRIVER-1750 Ensure contexts are always cancelled during server monitoring (mongodb#654) GODRIVER-1931 Sync new cursors and SDAM LB tests (mongodb#655) GODRIVER-1981 Sync new transactions tests (mongodb#652) GODRIVER-1931 Run tests against LBs in Evergreen (mongodb#648) ...
GODRIVER-1925
Checks for a possible cursor error in
DownloadStream#FillBuffer
instead of always returningerrNoMoreChunks
whends.cursor.Next
returns false. If there is a cursor error, closes the cursor and returns the underlying error.Adds a test to simulate a timeout during
DownloadStream#Read
and assert thatcontext deadline exceeded
is returned instead ofio.EOF
.