@@ -51,6 +51,7 @@ final class dml_read_replica_test extends \database_driver_testcase {
5151 * @param bool $wantlatency
5252 * @param mixed $readonly
5353 * @param mixed $dbclass
54+ * @param float|null $latency Override replica latency seconds.
5455 * @return read_replica_moodle_database $db
5556 */
5657 public function new_db (
@@ -60,16 +61,18 @@ public function new_db(
6061 ['dbhost ' => 'test_ro2 ' , 'dbport ' => 2 , 'dbuser ' => 'test2 ' , 'dbpass ' => 'test2 ' ],
6162 ['dbhost ' => 'test_ro3 ' , 'dbport ' => 3 , 'dbuser ' => 'test3 ' , 'dbpass ' => 'test3 ' ],
6263 ],
63- $ dbclass = read_replica_moodle_database::class
64+ $ dbclass = read_replica_moodle_database::class,
65+ ?float $ latency = null
6466 ): read_replica_moodle_database {
6567 $ dbhost = 'test_rw ' ;
6668 $ dbname = 'test ' ;
6769 $ dbuser = 'test ' ;
6870 $ dbpass = 'test ' ;
6971 $ prefix = 'test_ ' ;
7072 $ dboptions = ['readonly ' => ['instance ' => $ readonly , 'exclude_tables ' => ['exclude ' ]]];
71- if ($ wantlatency ) {
72- $ dboptions ['readonly ' ]['latency ' ] = self ::$ dbreadonlylatency ;
73+ $ effectivelatency = $ latency ?? ($ wantlatency ? self ::$ dbreadonlylatency : null );
74+ if ($ effectivelatency !== null ) {
75+ $ dboptions ['readonly ' ]['latency ' ] = $ effectivelatency ;
7376 }
7477
7578 $ db = new $ dbclass ();
@@ -373,6 +376,34 @@ public function test_long_update(): void {
373376 }
374377 }
375378
379+ /**
380+ * Test mark_tables_for_primary() routes reads to the writer until latency expires.
381+ */
382+ public function test_mark_tables_for_primary (): void {
383+ $ latency = 2 ;
384+ $ DB = $ this ->new_db (latency: $ latency );
385+
386+ // Check reads are going to the reader.
387+ $ handle = $ DB ->get_records ('table ' );
388+ $ this ->assert_readonly_handle ($ handle );
389+ $ readsreplica = $ DB ->perf_get_reads_replica ();
390+ $ this ->assertGreaterThan (0 , $ readsreplica );
391+
392+ $ DB ->mark_tables_for_primary ('table ' );
393+
394+ // Verify reads are now routed to the writer.
395+ $ handle = $ DB ->get_records ('table ' );
396+ $ this ->assertEquals ('test_rw::test:test ' , $ handle );
397+ $ this ->assertEquals ($ readsreplica , $ DB ->perf_get_reads_replica ());
398+
399+ sleep ($ latency + 1 );
400+
401+ // Past latency, reads should be routed back to the reader.
402+ $ handle = $ DB ->get_records ('table ' );
403+ $ this ->assert_readonly_handle ($ handle );
404+ $ this ->assertEquals ($ readsreplica + 1 , $ DB ->perf_get_reads_replica ());
405+ }
406+
376407 /**
377408 * Test readonly handle is not used with events
378409 * when the latency parameter is applied properly.
0 commit comments