Merge "API: Add assertuser parameter"
[lhc/web/wiklou.git] / includes / objectcache / SqlBagOStuff.php
index 73f8280..47dae78 100644 (file)
@@ -44,7 +44,7 @@ class SqlBagOStuff extends BagOStuff {
        /** @var string */
        protected $tableName = 'objectcache';
        /** @var bool */
-       protected $slaveOnly = false;
+       protected $replicaOnly = false;
        /** @var int */
        protected $syncTimeout = 3;
 
@@ -85,11 +85,11 @@ class SqlBagOStuff extends BagOStuff {
         *                  required to hold the largest shard index. Data will be
         *                  distributed across all tables by key hash. This is for
         *                  MySQL bugs 61735 and 61736.
-        *   - slaveOnly:   Whether to only use slave DBs and avoid triggering
+        *   - slaveOnly:   Whether to only use replica DBs and avoid triggering
         *                  garbage collection logic of expired items. This only
         *                  makes sense if the primary DB is used and only if get()
         *                  calls will be used. This is used by ReplicatedBagOStuff.
-        *   - syncTimeout: Max seconds to wait for slaves to catch up for WRITE_SYNC.
+        *   - syncTimeout: Max seconds to wait for replica DBs to catch up for WRITE_SYNC.
         *
         * @param array $params
         */
@@ -97,6 +97,7 @@ class SqlBagOStuff extends BagOStuff {
                parent::__construct( $params );
 
                $this->attrMap[self::ATTR_EMULATION] = self::QOS_EMULATION_SQL;
+               $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE;
 
                if ( isset( $params['servers'] ) ) {
                        $this->serverInfos = [];
@@ -119,6 +120,7 @@ class SqlBagOStuff extends BagOStuff {
                        // Default to using the main wiki's database servers
                        $this->serverInfos = false;
                        $this->numServers = 1;
+                       $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE;
                }
                if ( isset( $params['purgePeriod'] ) ) {
                        $this->purgePeriod = intval( $params['purgePeriod'] );
@@ -132,7 +134,7 @@ class SqlBagOStuff extends BagOStuff {
                if ( isset( $params['syncTimeout'] ) ) {
                        $this->syncTimeout = $params['syncTimeout'];
                }
-               $this->slaveOnly = !empty( $params['slaveOnly'] );
+               $this->replicaOnly = !empty( $params['slaveOnly'] );
        }
 
        protected function getSeparateMainLB() {
@@ -180,10 +182,10 @@ class SqlBagOStuff extends BagOStuff {
                                $this->logger->debug( __CLASS__ . ": connecting to $host" );
                                // Use a blank trx profiler to ignore expections as this is a cache
                                $info['trxProfiler'] = new TransactionProfiler();
-                               $db = DatabaseBase::factory( $type, $info );
+                               $db = Database::factory( $type, $info );
                                $db->clearFlag( DBO_TRX );
                        } else {
-                               $index = $this->slaveOnly ? DB_SLAVE : DB_MASTER;
+                               $index = $this->replicaOnly ? DB_REPLICA : DB_MASTER;
                                if ( $this->getSeparateMainLB() ) {
                                        $db = $this->getSeparateMainLB()->getConnection( $index );
                                        $db->clearFlag( DBO_TRX ); // auto-commit mode
@@ -377,7 +379,7 @@ class SqlBagOStuff extends BagOStuff {
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
                $ok = $this->setMulti( [ $key => $value ], $exptime );
                if ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) {
-                       $ok = $ok && $this->waitForSlaves();
+                       $ok = $this->waitForReplication() && $ok;
                }
 
                return $ok;
@@ -489,7 +491,7 @@ class SqlBagOStuff extends BagOStuff {
        public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
                $ok = $this->mergeViaCas( $key, $callback, $exptime, $attempts );
                if ( ( $flags & self::WRITE_SYNC ) == self::WRITE_SYNC ) {
-                       $ok = $ok && $this->waitForSlaves();
+                       $ok = $this->waitForReplication() && $ok;
                }
 
                return $ok;
@@ -539,7 +541,7 @@ class SqlBagOStuff extends BagOStuff {
        }
 
        protected function garbageCollect() {
-               if ( !$this->purgePeriod || $this->slaveOnly ) {
+               if ( !$this->purgePeriod || $this->replicaOnly ) {
                        // Disabled
                        return;
                }
@@ -797,26 +799,30 @@ class SqlBagOStuff extends BagOStuff {
                return !$this->serverInfos;
        }
 
-       protected function waitForSlaves() {
-               if ( $this->usesMainDB() ) {
-                       $lb = $this->getSeparateMainLB()
-                               ?: MediaWikiServices::getInstance()->getDBLoadBalancer();
-                       // Return if there are no slaves
-                       if ( $lb->getServerCount() <= 1 ) {
-                               return true;
-                       }
-                       // Main LB is used; wait for any slaves to catch up
-                       try {
-                               $pos = $lb->getMasterPos();
-                               if ( $pos ) {
-                                       return $lb->waitForAll( $pos, 3 );
-                               }
-                       } catch ( DBReplicationWaitError $e ) {
-                               return false;
-                       }
+       protected function waitForReplication() {
+               if ( !$this->usesMainDB() ) {
+                       // Custom DB server list; probably doesn't use replication
+                       return true;
                }
 
-               // Custom DB server list; probably doesn't use replication
-               return true;
+               $lb = $this->getSeparateMainLB()
+                       ?: MediaWikiServices::getInstance()->getDBLoadBalancer();
+
+               if ( $lb->getServerCount() <= 1 ) {
+                       return true; // no replica DBs
+               }
+
+               // Main LB is used; wait for any replica DBs to catch up
+               $masterPos = $lb->getMasterPos();
+
+               $loop = new WaitConditionLoop(
+                       function () use ( $lb, $masterPos ) {
+                               return $lb->waitForAll( $masterPos, 1 );
+                       },
+                       $this->syncTimeout,
+                       $this->busyCallbacks
+               );
+
+               return ( $loop->invoke() === $loop::CONDITION_REACHED );
        }
 }