/** @var string */
protected $tableName = 'objectcache';
/** @var bool */
- protected $slaveOnly = false;
+ protected $replicaOnly = false;
/** @var int */
protected $syncTimeout = 3;
* 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
*/
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 = [];
// 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'] );
if ( isset( $params['syncTimeout'] ) ) {
$this->syncTimeout = $params['syncTimeout'];
}
- $this->slaveOnly = !empty( $params['slaveOnly'] );
+ $this->replicaOnly = !empty( $params['slaveOnly'] );
}
protected function getSeparateMainLB() {
$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
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;
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;
}
protected function garbageCollect() {
- if ( !$this->purgePeriod || $this->slaveOnly ) {
+ if ( !$this->purgePeriod || $this->replicaOnly ) {
// Disabled
return;
}
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 );
}
}