Skip to content

fork within cursor loop leads to RuntimeException or ServerExpection #929

@raffis

Description

@raffis

Description

Creating forks within a mongodb cursor loop.
Having a hard time here. If the fork terminates, the cursor gets killed. Probably because the parents memory gets cloned into the fork and the driver kills the cursor after the fork exits.

Environment

Driver: 1.5.3
Lib: 1.4.2
php: 7.2.4
pcntl ext required

Test Script

<?php
require_once('vendor/autoload.php');

function fork($doc) {
    $pid = pcntl_fork();

     if (-1 === $pid) {
         throw new \Exception('failed to spawn');
     }

    if (!$pid) {
        var_dump("SPAWN", $doc);
        exit();
    }

    return $pid;
}

$mongodb = new \MongoDB\Client('mongodb://mongodb:27017/test');

try {
    $mongodb->test->createCollection(
    'test',
     [
      'capped' => true,
       'size' => 100000,
     ]
    );
} catch (RuntimeException $e) {
    if (48 !== $e->getCode()) {
        throw $e;
    }
}

$collection = $mongodb->test->test;
$collection->insertOne(['foo' => 'bar']);

$cursor = $collection->find([], [
    'cursorType' => \MongoDB\Operation\Find::TAILABLE_AWAIT
]);

$iterator = new \IteratorIterator($cursor);
$iterator->rewind();

while (true) {
   var_dump(getmypid(). "- loop");
   if ($iterator->valid()) {
        $document = $iterator->current();
        var_dump($document);
        fork($document);
   }

   $iterator->next();
}

Expected and Actual Behavior

Getting random cursor errors:

Fatal error: Uncaught MongoDB\Driver\Exception\ServerException: cursor id 92208694393 not found in /srv/t/test/test.php on line 53

MongoDB\Driver\Exception\ServerException: cursor id 92208694393 not found in /srv/t/test/test.php on line 53

Call Stack:
    0.0001     459800   1. {main}() /srv/t/test/test.php:0
    0.0652    2322016   2. IteratorIterator->next() /srv/t/test/test.php:53

or:

Fatal error: Uncaught MongoDB\Driver\Exception\RuntimeException: Invalid reply to getMore command. in /srv/t/test/test.php on line 53

MongoDB\Driver\Exception\RuntimeException: Invalid reply to getMore command. in /srv/t/test/test.php on line 53

Call Stack:
    0.0002     459800   1. {main}() /srv/t/test/test.php:0
    0.1092    2322016   2. IteratorIterator->next() /srv/t/test/test.php:53

I would expect, that the fork exits after doing some stuff with $doc and the parent process runs its while loop forever.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions