Uploaded image for project: 'PHP Driver: Library'
  1. PHP Driver: Library
  2. PHPLIB-335

ChangeStream::next() should increment key even if ResumeTokenException is thrown

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.3.1
    • Affects Version/s: 1.3.0
    • Component/s: None
    • None

      While reviewing the PR for PHPLIB-327, I noticed that the key is only incremented if resume token extraction is successful. In actuality, ChangeStream will already have advanced the underlying current cursor. If the current element is valid after advancing (i.e. we didn't poll the server and find that there's no new event to report), we should increment the key before attempting extraction by swapping the existing two lines:

      if ($this->valid()) {
          $this->key++; // Previously below $this->resumeToken assignment
          $this->resumeToken = $this->extractResumeToken($this->csIt->current());
      }
      

      Test case:

      public function testResumeTokenNotFoundAdvancesKey()
      {
          $pipeline =  [['$project' => ['_id' => 0 ]]];
      
          $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
          $changeStream = $operation->execute($this->getPrimaryServer());
      
          /* Note: we intentionally do not start iteration with rewind() to ensure
           * that we test extraction functionality within next(). */
          $this->insertDocument(['x' => 1]);
          $this->insertDocument(['x' => 2]);
          $this->insertDocument(['x' => 3]);
      
          try {
              $changeStream->rewind();
              $this->fail('ResumeTokenException was not thrown');
          } catch (ResumeTokenException $e) {}
      
          $this->assertSame(0, $changeStream->key());
      
          try {
              $changeStream->next();
              $this->fail('ResumeTokenException was not thrown');
          } catch (ResumeTokenException $e) {}
      
          $this->assertSame(1, $changeStream->key());
      
          try {
              $changeStream->next();
              $this->fail('ResumeTokenException was not thrown');
          } catch (ResumeTokenException $e) {}
      
          $this->assertSame(2, $changeStream->key());
      }
      

            Assignee:
            katherine.walker@mongodb.com Katherine Walker (Inactive)
            Reporter:
            jmikola@mongodb.com Jeremy Mikola
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: