Skip to content

Commit 230f68f

Browse files
committed
PHPLIB-1115: Fix waitForSnapshot() for MongoDB 7.0+
This fixes a bug in the original implementation where the method would return even if the query did not match a document. Instead, we should retry if either the query fails to match or a SnapshotUnavailable error is raised. This issue was only discovered due to increased snapshot latency in MongoDB 7.0-dev. In previous versions, the snapshot was always available by the subsequent queries in testSnapshotQueries(), which uses waitForSnapshot(). Additionally, usleep() is added to avoid spamming the server with retry attempts. The TODO item for hrtime() was also removed, as there's no significant benefit to using it in this context and it's return types are not as convenient as microtime().
1 parent 118f084 commit 230f68f

File tree

1 file changed

+9
-14
lines changed

1 file changed

+9
-14
lines changed

tests/DocumentationExamplesTest.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use function microtime;
2020
use function ob_end_clean;
2121
use function ob_start;
22+
use function usleep;
2223
use function var_dump;
2324
use function version_compare;
2425

@@ -1973,27 +1974,21 @@ private function waitForSnapshot(string $databaseName, string $collectionName):
19731974
$collection = new Collection($this->manager, $databaseName, $collectionName);
19741975
$session = $this->manager->startSession(['snapshot' => true]);
19751976

1976-
/* Retry until a snapshot query succeeds or ten seconds elapse,
1977-
* whichwever comes first.
1978-
*
1979-
* TODO: use hrtime() once the library requires PHP 7.3+ */
1977+
// Retry until a snapshot query succeeds or ten seconds elapse.
19801978
$retryUntil = microtime(true) + 10;
19811979

19821980
do {
19831981
try {
1984-
$collection->aggregate(
1985-
[['$match' => ['_id' => ['$exists' => true]]]],
1986-
['session' => $session]
1987-
);
1988-
1989-
break;
1982+
if ($collection->findOne([], ['session' => $session]) !== null) {
1983+
break;
1984+
}
19901985
} catch (CommandException $e) {
1991-
if ($e->getCode() === 246 /* SnapshotUnavailable */) {
1992-
continue;
1986+
if ($e->getCode() !== 246 /* SnapshotUnavailable */) {
1987+
throw $e;
19931988
}
1994-
1995-
throw $e;
19961989
}
1990+
1991+
usleep(1000);
19971992
} while (microtime(true) < $retryUntil);
19981993
}
19991994

0 commit comments

Comments
 (0)