[CSHARP-1724] IAsyncCursor Current property sometimes returns an empty batch Created: 25/Jul/16  Updated: 22/Oct/16  Resolved: 22/Oct/16

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 2.2.4
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Tristan Kilani-Freeman [X] Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The documentation for querying data with the c# driver here appears to sometimes fail if documents are too large, because MoveNextAsync() wrongly returns true, even though there are no more documents.

This can cause issues if you rely on MoveNextAsync to always behave as expected, and attempt to batch insert the results of cursor.Current(), as in the below example:

var initialColl = _database.GetCollection<BsonDocument>("initialCollection");
 
            await
                initialColl.InsertManyAsync(new[]
                {
                    new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                    new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                    new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                    new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                    new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                    new BsonDocument("binaryData", new BsonBinaryData(Enumerable.Repeat((byte) 0, 174707).ToArray())),
                });
 
            var numDocuments = await initialColl.CountAsync(x => true);
            if (numDocuments > 0)
            {
                var backup = _database.GetCollection<BsonDocument>("initialCollection_backup");
                var count = 0;
                using (var cursor = await initialColl.FindAsync(x => true))
                {
                    while (await cursor.MoveNextAsync())
                    {
                        var docBatch = cursor.Current.ToList();
                        count += docBatch.Count();
                        await backup.InsertManyAsync(docBatch);
                    }
                }
            }

In this example, the line:

var docBatch = cursor.Current.ToList()

retrieves all six items on the first iteration of the while loop, the loop then enters a second iteration where it retrieves an empty set of documents. The code then crashes on attempting to insert this empty set into the backup collection.

There are trivial workarounds (e.g. only inserting documents if any are returned, 'foreach'ing over the cursor etc.).



 Comments   
Comment by Robert Stam [ 22/Oct/16 ]

Closing this as "Works as Designed" since the driver only returns an empty batch if the server has returned an empty batch.

Older versions of the server sometimes returned on last empty batch at the end of the query. Current versions of the server no longer do.

Comment by Robert Stam [ 14/Oct/16 ]

I can reproduce using version 3.2.0 of the server, which does return one empty final batch.

One could argue that the driver is faithfully reporting to the application the batches that it is receiving from the server.

Aside from odd cases like this one, empty batches are also relevant when reading from a tailable collection, where an empty batch just means that there is no data available right now, but that the application should continue fetching new batches in case more data appears later.

Were you expecting the driver to silently skip over empty batches?

Comment by Robert Stam [ 14/Oct/16 ]

What version of the server were you using?

It's possible that earlier versions of the server are returning an empty batch. I'd like to test with the same version of the server that you were using when you saw this.

Comment by Robert Stam [ 14/Oct/16 ]

I am unable to reproduce this.

I get 6 documents back in the first (and only) batch.

I do not see a batch of zero documents.

Generated at Wed Feb 07 21:40:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.