use Wikimedia\Rdbms\DBError;
use Wikimedia\Rdbms\DBQueryError;
use Wikimedia\Rdbms\DBConnectionError;
+use Wikimedia\Rdbms\IMaintainableDatabase;
use Wikimedia\Rdbms\LoadBalancer;
use Wikimedia\ScopedCallback;
use Wikimedia\WaitConditionLoop;
*
* @ingroup Cache
*/
-class SqlBagOStuff extends BagOStuff {
+class SqlBagOStuff extends MediumSpecificBagOStuff {
/** @var array[] (server index => server config) */
protected $serverInfos;
/** @var string[] (server index => tag/host name) */
protected $tableName = 'objectcache';
/** @var bool */
protected $replicaOnly = false;
- /** @var int */
- protected $syncTimeout = 3;
/** @var LoadBalancer|null */
protected $separateMainLB;
protected $connFailureErrors = [];
/** @var int */
- private static $GARBAGE_COLLECT_DELAY_SEC = 1;
+ private static $GC_DELAY_SEC = 1;
/** @var string */
private static $OP_SET = 'set';
if ( isset( $params['shards'] ) ) {
$this->shards = intval( $params['shards'] );
}
- if ( isset( $params['syncTimeout'] ) ) {
- $this->syncTimeout = $params['syncTimeout'];
- }
// Backwards-compatibility for < 1.34
$this->replicaOnly = $params['replicaOnly'] ?? ( $params['slaveOnly'] ?? false );
}
* Get a connection to the specified database
*
* @param int $serverIndex
- * @return Database
+ * @return IMaintainableDatabase
* @throws MWException
*/
protected function getDB( $serverIndex ) {
# Don't keep timing out trying to connect for each call if the DB is down
if (
isset( $this->connFailureErrors[$serverIndex] ) &&
- ( time() - $this->connFailureTimes[$serverIndex] ) < 60
+ ( $this->getCurrentTime() - $this->connFailureTimes[$serverIndex] ) < 60
) {
throw $this->connFailureErrors[$serverIndex];
}
$index = $this->replicaOnly ? DB_REPLICA : DB_MASTER;
if ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' ) {
// Keep a separate connection to avoid contention and deadlocks
- $db = $lb->getConnection( $index, [], false, $lb::CONN_TRX_AUTOCOMMIT );
+ $db = $lb->getConnectionRef( $index, [], false, $lb::CONN_TRX_AUTOCOMMIT );
} else {
// However, SQLite has the opposite behavior due to DB-level locking.
// Stock sqlite MediaWiki installs use a separate sqlite cache DB instead.
- $db = $lb->getConnection( $index );
+ $db = $lb->getConnectionRef( $index );
}
}
$keysByTable[$serverIndex][$tableName][] = $key;
}
- $exptime = $this->convertToExpiry( $exptime );
+ $exptime = $this->getExpirationAsTimestamp( $exptime );
$result = true;
/** @noinspection PhpUnusedLocalVariableInspection */
return $this->modifyMulti( [ $key => $value ], $exptime, $flags, self::$OP_SET );
}
- public function add( $key, $value, $exptime = 0, $flags = 0 ) {
+ protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
return $this->modifyMulti( [ $key => $value ], $exptime, $flags, self::$OP_ADD );
}
- protected function cas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
+ protected function doCas( $casToken, $key, $value, $exptime = 0, $flags = 0 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
- $exptime = $this->convertToExpiry( $exptime );
+ $exptime = $this->getExpirationAsTimestamp( $exptime );
/** @noinspection PhpUnusedLocalVariableInspection */
$silenceScope = $this->silenceTransactionProfiler();
return $ok;
}
- protected function doChangeTTLMulti( array $keys, $exptime, $flags = 0 ) {
+ public function changeTTLMulti( array $keys, $exptime, $flags = 0 ) {
return $this->modifyMulti(
array_fill_keys( $keys, null ),
$exptime,
protected function isExpired( $db, $exptime ) {
return (
$exptime != $this->getMaxDateTime( $db ) &&
- wfTimestamp( TS_UNIX, $exptime ) < time()
+ wfTimestamp( TS_UNIX, $exptime ) < $this->getCurrentTime()
);
}
* @return string
*/
protected function getMaxDateTime( $db ) {
- if ( time() > 0x7fffffff ) {
+ if ( (int)$this->getCurrentTime() > 0x7fffffff ) {
return $db->timestamp( 1 << 62 );
} else {
return $db->timestamp( 0x7fffffff );
// Only purge on one in every $this->purgePeriod writes
mt_rand( 0, $this->purgePeriod - 1 ) == 0 &&
// Avoid repeating the delete within a few seconds
- ( time() - $this->lastGarbageCollect ) > self::$GARBAGE_COLLECT_DELAY_SEC
+ ( $this->getCurrentTime() - $this->lastGarbageCollect ) > self::$GC_DELAY_SEC
) {
$garbageCollector = function () use ( $db ) {
- $this->deleteServerObjectsExpiringBefore( $db, time(), null, $this->purgeLimit );
+ $this->deleteServerObjectsExpiringBefore(
+ $db, $this->getCurrentTime(),
+ null,
+ $this->purgeLimit
+ );
$this->lastGarbageCollect = time();
};
if ( $this->asyncHandler ) {
- $this->lastGarbageCollect = time(); // avoid duplicate enqueues
+ $this->lastGarbageCollect = $this->getCurrentTime(); // avoid duplicate enqueues
( $this->asyncHandler )( $garbageCollector );
} else {
$garbageCollector();
}
public function expireAll() {
- $this->deleteObjectsExpiringBefore( time() );
+ $this->deleteObjectsExpiringBefore( $this->getCurrentTime() );
}
public function deleteObjectsExpiringBefore(
protected function markServerDown( DBError $exception, $serverIndex ) {
unset( $this->conns[$serverIndex] ); // bug T103435
+ $now = $this->getCurrentTime();
if ( isset( $this->connFailureTimes[$serverIndex] ) ) {
- if ( time() - $this->connFailureTimes[$serverIndex] >= 60 ) {
+ if ( $now - $this->connFailureTimes[$serverIndex] >= 60 ) {
unset( $this->connFailureTimes[$serverIndex] );
unset( $this->connFailureErrors[$serverIndex] );
} else {
return;
}
}
- $now = time();
$this->logger->info( __METHOD__ . ": Server #$serverIndex down until " . ( $now + 60 ) );
$this->connFailureTimes[$serverIndex] = $now;
$this->connFailureErrors[$serverIndex] = $exception;