farzan
farzan

Reputation: 1170

PHP MongoDb driver: How to set timeout for executing a code

I have the following code which executes a piece of code on the MongoDb's side:

$mongoCode = new MongoCode('/* Some JS code */');
$db->execute($mongoCode, array(
    'socketTimeoutMS' => 1000000,
));

As you see I have tried to set timeout for the code's execution by setting the socketTimeoutMS value in second parameter of execute() function. But it does not work. Documentations in PHP website indicate that the second parameter of execute() command is sent to code as arguments. How can I set timeout for MongoDB::execute()? Please note that I am using version 1.5 of MongoDB driver for php and MongoCursor::$timeout is deprecated and does not work anymore.

Upvotes: 4

Views: 7482

Answers (2)

Christian P
Christian P

Reputation: 12240

You can set the socketTimeoutMS on MongoClient:

$mongo = new MongoClient("mongodb://localhost:27017", 
    array(
        "socketTimeoutMS" => 100000
    )
); 

The args parameters for the execute method are passed to the code not to the driver.

You can also set a timeout just when executing the command:

$result = $mongo->dbname->command(
    ['eval' => $code],
    ['socketTimeoutMS' => 1]
);

Alternatively, if you're not executing commands, you can set the timeout on the cursor:

$cursor = $collection->find([]);
$cursor->timeout(10000);

This will obviously not work on the execute command, because that command doesn't return a cursor.

Upvotes: 7

Neil Lunn
Neil Lunn

Reputation: 151112

You want the MongoDB::command implementation for this which actually accepts the argument:

<?php
$mongo = new MongoClient('mongodb://192.168.2.3/test');
$db = $mongo->test;

$code = new MongoCode( 'sleep(100); return "hello";' );
try {
  $res = $db->command(
    array("eval" => $code),
    array( 'socketTimeoutMS' => 1 )
  );


  echo var_dump( $res );

} catch (Exception $e) {

  echo 'Caught exception: ', $e->getMessage(), "\n";

}

?>

Note that even though the exception will be thrown for the timeout, this does not not actually stop the code running on the server. That you would have to handle yourself.

Look into the killOp() and currentOP() methods, with their usage and implementation for a way to control and processes left running after your timeout expires on this operation.

Really try to look for other approaches rather than executing JavaScript on the server like this.

Upvotes: 0

Related Questions