Renames preparatory to parser tests refactor
[lhc/web/wiklou.git] / maintenance / Maintenance.php
index ab316c0..6e1f741 100644 (file)
@@ -37,6 +37,7 @@ define( 'DO_MAINTENANCE', RUN_MAINTENANCE_IF_MAIN ); // original name, harmless
 $maintClass = false;
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Abstract maintenance class for quickly writing and churning out
@@ -108,7 +109,7 @@ abstract class Maintenance {
        private $mDb = null;
 
        /** @var float UNIX timestamp */
-       private $lastSlaveWait = 0.0;
+       private $lastReplicationWait = 0.0;
 
        /**
         * Used when creating separate schema files.
@@ -548,6 +549,46 @@ abstract class Maintenance {
 
        }
 
+       /**
+        * Set triggers like when to try to run deferred updates
+        * @since 1.28
+        */
+       public function setTriggers() {
+               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               self::setLBFactoryTriggers( $lbFactory );
+       }
+
+       /**
+        * @param LBFactory $LBFactory
+        * @since 1.28
+        */
+       public static function setLBFactoryTriggers( LBFactory $LBFactory ) {
+               // Hook into period lag checks which often happen in long-running scripts
+               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               $lbFactory->setWaitForReplicationListener(
+                       __METHOD__,
+                       function () {
+                               global $wgCommandLineMode;
+                               // Check config in case of JobRunner and unit tests
+                               if ( $wgCommandLineMode ) {
+                                       DeferredUpdates::tryOpportunisticExecute( 'run' );
+                               }
+                       }
+               );
+               // Check for other windows to run them. A script may read or do a few writes
+               // to the master but mostly be writing to something else, like a file store.
+               $lbFactory->getMainLB()->setTransactionListener(
+                       __METHOD__,
+                       function ( $trigger ) {
+                               global $wgCommandLineMode;
+                               // Check config in case of JobRunner and unit tests
+                               if ( $wgCommandLineMode && $trigger === IDatabase::TRIGGER_COMMIT ) {
+                                       DeferredUpdates::tryOpportunisticExecute( 'run' );
+                               }
+                       }
+               );
+       }
+
        /**
         * Run a child maintenance script. Pass all of the current arguments
         * to it.
@@ -1186,7 +1227,7 @@ abstract class Maintenance {
         * If not set, wfGetDB() will be used.
         * This function has the same parameters as wfGetDB()
         *
-        * @param integer $db DB index (DB_SLAVE/DB_MASTER)
+        * @param integer $db DB index (DB_REPLICA/DB_MASTER)
         * @param array $groups; default: empty array
         * @param string|bool $wiki; default: current wiki
         * @return IDatabase
@@ -1223,23 +1264,29 @@ abstract class Maintenance {
        }
 
        /**
-        * Commit the transcation on a DB handle and wait for slaves to catch up
+        * Commit the transcation on a DB handle and wait for replica DBs to catch up
         *
         * This method makes it clear that commit() is called from a maintenance script,
         * which has outermost scope. This is safe, unlike $dbw->commit() called in other places.
         *
         * @param IDatabase $dbw
         * @param string $fname Caller name
-        * @return bool Whether the slave wait succeeded
+        * @return bool Whether the replica DB wait succeeded
         * @since 1.27
         */
        protected function commitTransaction( IDatabase $dbw, $fname ) {
                $dbw->commit( $fname );
+               try {
+                       $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+                       $lbFactory->waitForReplication(
+                               [ 'timeout' => 30, 'ifWritesSince' => $this->lastReplicationWait ]
+                       );
+                       $this->lastReplicationWait = microtime( true );
 
-               $ok = wfWaitForSlaves( $this->lastSlaveWait, false, '*', 30 );
-               $this->lastSlaveWait = microtime( true );
-
-               return $ok;
+                       return true;
+               } catch ( DBReplicationWaitError $e ) {
+                       return false;
+               }
        }
 
        /**