MongoDB and PHP Library Cursor Timeout

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



MongoDB and PHP Library Cursor Timeout



While using official MongoDB's PHP Library (https://docs.mongodb.com/php-library/master/tutorial/install-php-library/), how to set the cursor timeout as infinite? I read mixed documentation and it's often hard to understand if it refers to the old PHP Driver or the new one (which I am talking about).



For instance:


$cursor = $col->find();
foreach ($cursor as $document)
// slow code..



How to prevent the cursor from timing out (see error below) and making sure the cursor is closed afterwards without any memory leaks?


Fatal error: Uncaught MongoDBDriverExceptionRuntimeException:
cursor id 123456789 not found in /var/www/html/code.php:1



There are some similar questions here (like this) but it seems we lack a definite reference.





Have you tried setting noCursorTimeout option (although not a good idea because setting cursor timeout as infinite as will keep the cursor open for forever) for find operation or specify batchSize for query ?
– Veeram
Aug 13 at 17:45


noCursorTimeout


batchSize





re noCursorTimeout .. but then how to close the cursor manually? just setting this option to true seems to be just half of the solution?
– JoeSlav
Aug 13 at 18:15





I agree that is not even a recommend option. I'm afraid I don't know a way to close the cursor from client side ( may be cursor.close when error is intercepted ) but one can set timeout on the server. Something like mongod --setParameter cursorTimeoutMillis=time in millis kills the cursor after a timeout. What about the other solution ? using batchsize ? Set to lower number so your slow code have enough time to run and request the results frequently on the server.
– Veeram
Aug 13 at 19:26



mongod --setParameter cursorTimeoutMillis=time in millis





Which PHPLIB version are you using ? Also, did you try to set batchSize() as mentioned on the other post ?
– Wan Bachtiar
Aug 14 at 7:19


batchSize()





I use: MongoDB server version: 4.0.1 / pecl mongodb 1.4.3 stable / Library is probably 1.3.2. I have not fiddle yet with batchSize as I am debating as to whether that will cause races in my code. But your point is understood. Thanks to both!
– JoeSlav
Aug 14 at 8:02




1 Answer
1



cursor id 123456789 not found in /var/www/html/code.php:1



Typically this is because the application is spending too long between getMore commands. In other words, the cursor returns a number of records on the first iteration and the loop takes a long time before it requests more records.


$cursor = $collection->find( [ 'field' => 'foobar'] );
foreach ($cursor as $document)
// long running processes (slow)



Cursors have a timeout on the server, after ~10 minutes if the client has not sent any commands to the server it will be closed due to inactivity. In the case above, when it's requesting for the next batch, the cursor has been killed resulting in the error message cursor id not found.


cursor id not found



Some tried to disable the cursor timeouts by setting noCursorTimeout:true on the cursor. Although this is not recommended, because you may end up with a cursor that lives forever (zombie) when there's an issue with getMore results returning from the server. i.e. cursors with noCursorTimeout may remain alive on the server long after the client disconnected.


noCursorTimeout:true


getMore


noCursorTimeout



There are a couple of possible solutions:



Decrease cursor.batchSize(). This is because reducing the number of records per batch reduces the cursor inactivity. i.e. Previously 100 records processed for 15 minutes, now it's only 50 records for 7.5 minutes.



Manually create a session i.e. PHPLIB MongoDBClient::startSession(). Then pass this as a session option on the queries. At regular intervals during the long-running iteration, perform some other database interaction using the same session i.e. ping the server. This will keep the session active (30 minutes timeout); however, it will do nothing to keep the cursor alive, so you may combine this with the use of noCursorTimeout.


session


session


noCursorTimeout






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard