Uploaded image for project: 'PHP Driver: Extension'
  1. PHP Driver: Extension
  2. PHPC-871

ConnectionTimeoutException on parent after forked child has finished its work

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 1.2.0, 1.2.1, 1.2.2
    • Component/s: None
    • None
    • Environment:
      Debian 8.6, PHP 5.6, php5.6-mongodb, MongoDB 3.2.10

      Hello,

      After updating the php driver to 1.2.2 (from 1.1.9), we encoutered ConnectionTimeoutException on our forked processes, forcing us to downgrade to 1.1.9 (or 1.1.10).

      Here's a script that will throw the exception :

      <?php
      
      
      $manager = new MongoDB\Driver\Manager("mongodb://localhost:27018");
      
      $bulk = new MongoDB\Driver\BulkWrite;
      $bulk->insert(['x' => 1]);
      $bulk->insert(['x' => 2]);
      $bulk->insert(['x' => 3]);
      $manager->executeBulkWrite('test.toto', $bulk);
      
      $pid = pcntl_fork();
      
      if ($pid == -1) {
          die('duplication impossible');
      } else if ($pid) {
          //Parent
          sleep(2); // We wait for the child to finish
          echo "In the parent process".PHP_EOL;
          $filter = ['x' => ['$gt' => 1]];
          $options = [
              'projection' => ['_id' => 0],
              'sort' => ['x' => -1],
          ];
      
          $query = new MongoDB\Driver\Query($filter, $options);
          $cursor = $manager->executeQuery('test.toto', $query);// And here occurs the error
      
          foreach ($cursor as $document) {
             var_dump($document);
          }
      
      } else {
          //Child
          echo "In the child process".PHP_EOL;
          $filter = ['x' => ['$gt' => 1]];
          $options = [
              'projection' => ['_id' => 0],
              'sort' => ['x' => -1],
          ];
      
          $query = new MongoDB\Driver\Query($filter, $options);
          $cursor = $manager->executeQuery('test.toto', $query);
      
          foreach ($cursor as $document) {
             var_dump($document);
          }
      }
      

      Easy script, it writes to a collection before forking. Then the child reads (with success) the written objects, while the father waits a few seconds and then also reads the written objects.

      Here's the output :

       > php generate_fork_mongo.php
      In the child process
      /home/admro/generate_fork_mongo.php:46:
      class stdClass#6 (1) {
        public $x =>
        int(3)
      }
      /home/admro/generate_fork_mongo.php:46:
      class stdClass#7 (1) {
        public $x =>
        int(2)
      }
      In the parent process
      PHP Fatal error:  Uncaught exception 'MongoDB\Driver\Exception\ConnectionTimeoutException' with message 'Failed to send "find" command with database "test": Failure during socket delivery: Broken pipe (32)' in /home/admro/generate_fork_mongo.php:27
      Stack trace:
      #0 /home/admro/generate_fork_mongo.php(27): MongoDB\Driver\Manager->executeQuery('test.toto', Object(MongoDB\Driver\Query))
      #1 {main}
        thrown in /home/admro/generate_fork_mongo.php on line 27
      

      Also find attached the output of mongodb.debug.

      My guess is that once the child has finished working, it closes the connection without the parent knowing. Then the parent tries to use the connection and throws the exception.

      Best regards,
      Bastien Diederichs

            Assignee:
            jmikola@mongodb.com Jeremy Mikola
            Reporter:
            b.dieder@prismamedia.com Bastien Diederichs
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: