-
Type: Improvement
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
Cursor has a TryNext method, but it's sort of confusing what it does. At first glance, it sounds like it'd return the next document of the underlying cursor batch if available, and return false if that's empty and a getMore would have to be issued. However, that's not what it does; instead, it will always issue a getMore if needed; the "try" variant simply prevents a subsequent getMore from being issued if no documents were returned.
The simplest thing to do would be to add an IsBatchEmpty/WouldNextBlock/BatchDocsRemaining/etc... method. You could also add a 3rd variant of Next, though that'd probably make things even more confusing.
As a workaround, I'm basically writing my tailer to look something like:
cursor, err := client.Database("foo").Collection("bar").Find(ctx, bson.D{}, options.Find().SetCursorType(options.TailableAwait)) if err != nil { return err } defer cursor.Close(ctx) if err == nil { // Create a context that will cause any blocking call (i.e. `getMore`) // to fail; when this happens we'll sleep for a bit to prevent DoS'ing // the node. canceledCtx, cancel := context.WithCancel(ctx) cancel() nextCtx := canceled for { for cursor.TryNext(nextCtx) { nextCtx = canceledCtx // Process current doc... } if err := cursor.Err(); err == context.Canceled { // The driver must have tried to issue a `getMore`; sleep // for a bit and then allow `TryNext` to block once. time.Sleep(100 * time.Millisecond) nextCtx = ctx continue } else if err != nil { break } } } // Handle cursor error...
If I had something like IsBatchEmpty, I could write this as:
cursor, err := client.Database("foo").Collection("bar").Find(ctx, bson.D{}, options.Find().SetCursorType(options.TailableAwait)) if err != nil { return err } defer cursor.Close(ctx) if err == nil { for cursor.TryNext(ctx) { // Process current doc... if cursor.IsBatchEmpty() { // Avoid sending too many `getMore`s. time.Sleep(100 * time.Millisecond) } } err = cursor.Err() } // Handle cursor error...
- related to
-
GODRIVER-2992 ChangeStream should expose a RemainingBatchLength method like Cursor does
- Closed