1--TEST-- 2Causal consistency: second read's afterClusterTime uses last reply's operationTime 3--SKIPIF-- 4<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?> 5<?php skip_if_not_libmongoc_crypto(); ?> 6<?php skip_if_not_replica_set_or_mongos_with_replica_set(); ?> 7<?php skip_if_server_version('<', '3.6'); ?> 8<?php skip_if_not_clean(); ?> 9--FILE-- 10<?php 11require_once __DIR__ . "/../utils/basic.inc"; 12 13class Test implements MongoDB\Driver\Monitoring\CommandSubscriber 14{ 15 private $lastSeenOperationTime; 16 17 public function executeReadAfterRead() 18 { 19 $this->lastSeenOperationTime = null; 20 21 MongoDB\Driver\Monitoring\addSubscriber($this); 22 23 $manager = new MongoDB\Driver\Manager(URI); 24 $session = $manager->startSession(); 25 26 $query = new MongoDB\Driver\Query([]); 27 $manager->executeQuery(NS, $query, ['session' => $session]); 28 $manager->executeQuery(NS, $query, ['session' => $session]); 29 30 MongoDB\Driver\Monitoring\removeSubscriber($this); 31 } 32 33 public function executeReadAfterWrite() 34 { 35 $this->lastSeenOperationTime = null; 36 37 MongoDB\Driver\Monitoring\addSubscriber($this); 38 39 $manager = new MongoDB\Driver\Manager(URI); 40 $session = $manager->startSession(); 41 42 $bulk = new MongoDB\Driver\BulkWrite; 43 $bulk->insert(['x' => 1]); 44 $manager->executeBulkWrite(NS, $bulk, ['session' => $session]); 45 46 $query = new MongoDB\Driver\Query([]); 47 $manager->executeQuery(NS, $query, ['session' => $session]); 48 49 MongoDB\Driver\Monitoring\removeSubscriber($this); 50 } 51 52 public function commandStarted(MongoDB\Driver\Monitoring\CommandStartedEvent $event) 53 { 54 $command = $event->getCommand(); 55 $hasAfterClusterTime = isset($command->readConcern->afterClusterTime); 56 printf("%s command includes afterClusterTime: %s\n", $event->getCommandName(), ($hasAfterClusterTime ? 'yes' : 'no')); 57 58 if ($hasAfterClusterTime && $this->lastSeenOperationTime !== null) { 59 printf("%s command uses last seen operationTime: %s\n", $event->getCommandName(), ($command->readConcern->afterClusterTime == $this->lastSeenOperationTime) ? 'yes' : 'no'); 60 } 61 } 62 63 public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event) 64 { 65 $reply = $event->getReply(); 66 $hasOperationTime = isset($reply->operationTime); 67 68 printf("%s command reply includes operationTime: %s\n", $event->getCommandName(), $hasOperationTime ? 'yes' : 'no'); 69 70 if ($hasOperationTime) { 71 $this->lastSeenOperationTime = $reply->operationTime; 72 } 73 } 74 75 public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event) 76 { 77 } 78} 79 80echo "Testing read after read\n"; 81(new Test)->executeReadAfterRead(); 82 83echo "\nTesting read after write\n"; 84(new Test)->executeReadAfterWrite(); 85 86?> 87===DONE=== 88<?php exit(0); ?> 89--EXPECT-- 90Testing read after read 91find command includes afterClusterTime: no 92find command reply includes operationTime: yes 93find command includes afterClusterTime: yes 94find command uses last seen operationTime: yes 95find command reply includes operationTime: yes 96 97Testing read after write 98insert command includes afterClusterTime: no 99insert command reply includes operationTime: yes 100find command includes afterClusterTime: yes 101find command uses last seen operationTime: yes 102find command reply includes operationTime: yes 103===DONE=== 104