[CDRIVER-1221] mongoc_cursor_is_alive() returns false for live cursor from find command Created: 05/May/16  Updated: 10/Aug/16  Resolved: 10/May/16

Status: Closed
Project: C Driver
Component/s: libmongoc
Affects Version/s: 1.4.0
Fix Version/s: 1.4.0

Type: Bug Priority: Major - P3
Reporter: Jeremy Mikola Assignee: A. Jesse Jiryu Davis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
is depended on by PHPC-673 Cursor::isDead() returns true despite... Closed
Related
related to CDRIVER-1234 Inconsistent error reporting when adv... Closed

 Description   

After upgrading PHPC and HHVM to 1.4.0-dev, we started seeing some failed tests that were asserting whether a cursor returned by a find command was dead or alive (PHPC-673). If we change the test to use OP_QUERY by connecting to a 3.0 (or earlier) server, it passes. The current logic is:

return (!cursor->sent ||
        (!CURSOR_FAILED (cursor) &&
         !cursor->done &&
         (cursor->rpc.header.opcode == MONGOC_OPCODE_REPLY) &&
         cursor->rpc.reply.cursor_id));

The last change to this code was the addition of CURSOR_FAILED() in a3d0fe2 for CDRIVER-838, which I don't believe is related since it predates 1.4.0-dev.

Some debugging revealed that cursor->rpc.header.opcode is the cause. For a freshly executed query on its first batch (of two), I observed the following:

cursor->sent: 1
CURSOR_FAILED: 0
cursor->done: 0
cursor->rpc.header.opcode: 0
cursor->rpc.reply.cursor_id: 2061799758

We would expect cursor->rpc.header.opcode to be 1 (i.e. MONGOC_OPCODE_REPLY) here, as it is with a legacy OP_QUERY or on any 1.3.x version of libmongoc. This appears to be a regression.



 Comments   
Comment by Githook User [ 19/May/16 ]

Author:

{u'username': u'jmikola', u'name': u'Jeremy Mikola', u'email': u'jmikola@gmail.com'}

Message: PHPC-673: Fix Cursor::isDead() tests for mongoc_cursor_is_alive()

This changes our tests based on upstream fixes for mongoc_cursor_is_alive() in CDRIVER-1221.
Branch: master
https://github.com/mongodb/mongo-php-driver/commit/c0046a3e631cd412f5673f4ae2b04c9210a04b3e

Comment by A. Jesse Jiryu Davis [ 10/May/16 ]

AFAICT as far back as 1.2.0, if you have more than 101 docs in a collection and do "find", "is_alive" is false after the 101st document.

Comment by Jeremy Mikola [ 10/May/16 ]

Furthermore, there was a bug where a multi-batch cursor was not "alive" after the first batch, a bug which predates 1.2.0. That bug is fixed in the patch for this issue.

If I understand correctly, we should be able to verify this long-standing bug by tweaking our tests to iterate over three batches instead of two? With the bugged behavior, we would see the cursor marked as dead during the middle batch, when it is very much still alive.

Comment by A. Jesse Jiryu Davis [ 10/May/16 ]

Actually, I've tested back to 1.2.0 with MongoDB 2.6 (so, before the "find" command), and the behavior seems consistent: it's not until after mongoc_cursor_next has returned NULL that mongoc_cursor_is_alive is false.

Furthermore, there was a bug where a multi-batch cursor was not "alive" after the first batch, a bug which predates 1.2.0. That bug is fixed in the patch for this issue.

Comment by A. Jesse Jiryu Davis [ 09/May/16 ]

My fix wasn't correct at the final document. If there are 3 documents and batch size is 2, mongoc_cursor_is_alive should be true after the first 2 calls to mongoc_cursor_next, then false after the 3rd call. Instead, it's false after the 4th call (the first call to mongoc_cursor_next that returns false).

Comment by Githook User [ 09/May/16 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-1221 fix mongoc_cursor_is_alive
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/d6731fb93d8121b9ff36182f227621c10d996c5f

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