-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
None
-
Go Drivers
-
Not Needed
-
None
-
None
-
None
-
None
-
None
-
None
Detailed steps to reproduce the problem?
According to the CSOT specifications, the timeoutMS value must apply to cursor iteration methods such as cursor.Next():
When applying the timeoutMS option to next calls on cursor, drivers MUST ensure it applies to the entire call, not individual commands.
To reproduce:
func TestClientLevelTimeoutForCursors(t *testing.T) { client, err := mongo.Connect(options.Client().SetTimeout(500 * time.Millisecond)) require.NoError(t, err, "failed to connect to server") t.Cleanup(func() { _ = client.Disconnect(context.Background()) }) db := client.Database("exampleDB") collName := "exampleCappedCollection" // Drop the collection if it exists _ = db.Collection(collName).Drop(context.Background()) // Create a capped collection. collOpts := options.CreateCollection().SetCapped(true).SetSizeInBytes(1024 * 1024) // 1 MB capped collection err = db.CreateCollection(context.Background(), collName, collOpts) require.NoError(t, err, "failed to create capped collection") coll := db.Collection(collName) // Insert some documents to ensure the collection exists _, err = coll.InsertMany(context.Background(), []interface{}{ bson.D{{Key: "name", Value: "Alice"}}, bson.D{{Key: "name", Value: "Bob"}}, bson.D{{Key: "name", Value: "Charlie"}}, }) require.NoError(t, err, "failed to insert documents") opts := options.Find().SetMaxAwaitTime(10 * time.Second).SetBatchSize(3).SetCursorType(options.TailableAwait) res, err := coll.Find(context.Background(), bson.D{}, opts) if err != nil { t.Logf("error running Find with MaxAwaitTime: %v", err) } fmt.Println("Cursor created with MaxAwaitTime set to 10 seconds") //assert.Error(t, err, "expected validation error when using MaxAwaitTime with a non-capped collection") // What happens if we use the decoder? for res.Next(context.Background()) { fmt.Println("Found document:", res.Current) } if err := res.Err(); err != nil { t.Errorf("cursor error: %v", err) } }
Output:
❯ go test -run "TestClientLevelTimeoutForCursors" -v -failfast === RUN TestClientLevelTimeoutForCursors Cursor created with MaxAwaitTime set to 10 seconds Found document: {"_id": {"$oid":"687ed19e6478f989450d6e9b"},"name": "Alice"} Found document: {"_id": {"$oid":"687ed19e6478f989450d6e9c"},"name": "Bob"} Found document: {"_id": {"$oid":"687ed19e6478f989450d6e9d"},"name": "Charlie"}
Blocks indefinitely, running a getMore every 10 seconds=maxAwaitTimeMS:
{"getMore": {"$numberLong":"2425290832589901730"},"collection": "exampleCappedCollection","batchSize": {"$numberInt":"3"},"maxTimeMS": {"$numberLong":"10000"},"lsid": {"id": {"$binary":{"base64":"S8lu41B+R726FrVRyjWk0g==","subType":"04"}}},"$clusterTime": {"clusterTime": {"$timestamp":{"t":1753141637,"i":5}},"signature": {"hash": {"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"00"}},"keyId": {"$numberLong":"0"}}},"$db": "exampleDB"}
Definition of done: what must be done to consider the task complete?
The methods that use (*mongo.Cursor).next() should respect the effective timeoutMS for the full duration of the call, both for the operational level context deadlines (supported) and client-level timeouts.
- related to
-
GODRIVER-3473 Incorrect Validation of timeoutMS for Tailable AwaitData Cursors
-
- Closed
-
-
GODRIVER-3444 Clarify maxAwaitTimeMS adjustment by timeoutMS and RTT
-
- Closed
-