26use InvalidArgumentException;
27use Wikimedia\ObjectFactory\ObjectFactory;
50 private static $UPGRADE_TTL = 3600;
78 if ( empty(
$params[
'caches'] ) || !is_array(
$params[
'caches'] ) ) {
79 throw new InvalidArgumentException(
80 __METHOD__ .
': "caches" parameter must be an array of caches'
85 foreach (
$params[
'caches'] as $cacheInfo ) {
87 $this->caches[] = $cacheInfo;
89 $this->caches[] = ObjectFactory::getObjectFromSpec( $cacheInfo );
95 $this->asyncWrites = (
96 isset(
$params[
'replication'] ) &&
97 $params[
'replication'] ===
'async' &&
98 is_callable( $this->asyncHandler )
101 $this->cacheIndexes = array_keys( $this->caches );
104 public function get( $key, $flags = 0 ) {
105 $args = func_get_args();
111 return $this->callKeyMethodOnTierCache(
123 foreach ( $this->cacheIndexes as $i ) {
124 $value = $this->callKeyMethodOnTierCache(
131 if ( $value !==
false ) {
143 $this->callKeyWriteMethodOnTierCaches(
148 [ $key, $value, self::$UPGRADE_TTL ]
155 public function set( $key, $value, $exptime = 0, $flags = 0 ) {
156 return $this->callKeyWriteMethodOnTierCaches(
165 public function delete( $key, $flags = 0 ) {
166 return $this->callKeyWriteMethodOnTierCaches(
175 public function add( $key, $value, $exptime = 0, $flags = 0 ) {
177 $ok = $this->callKeyMethodOnTierCache(
189 $okSecondaries = $this->callKeyWriteMethodOnTierCaches(
190 array_slice( $this->cacheIndexes, 1 ),
194 [ $key, $value, $exptime, $flags ]
196 if ( $okSecondaries ===
false ) {
204 public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
205 return $this->callKeyWriteMethodOnTierCaches(
214 public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
215 return $this->callKeyWriteMethodOnTierCaches(
224 public function lock( $key, $timeout = 6, $exptime = 6, $rclass =
'' ) {
226 return $this->callKeyMethodOnTierCache(
237 return $this->callKeyMethodOnTierCache(
248 callable $progress =
null,
253 foreach ( $this->caches as $cache ) {
254 if ( $cache->deleteObjectsExpiringBefore( $timestamp, $progress, $limit, $tag ) ) {
262 public function getMulti( array $keys, $flags = 0 ) {
265 foreach ( $keys as $key ) {
266 $val = $this->
get( $key, $flags );
267 if ( $val !==
false ) {
275 public function setMulti( array $valueByKey, $exptime = 0, $flags = 0 ) {
276 return $this->callKeyWriteMethodOnTierCaches(
286 return $this->callKeyWriteMethodOnTierCaches(
296 return $this->callKeyWriteMethodOnTierCaches(
305 public function incrWithInit( $key, $exptime, $step = 1, $init =
null, $flags = 0 ) {
306 return $this->callKeyWriteMethodOnTierCaches(
316 parent::setMockTime( $time );
317 foreach ( $this->caches as $cache ) {
318 $cache->setMockTime( $time );
333 private function callKeyMethodOnTierCache( $index, $method, $arg0Sig, $rvSig, array $args ) {
334 return $this->caches[$index]->proxyCall( $method, $arg0Sig, $rvSig, $args, $this );
348 private function callKeyWriteMethodOnTierCaches(
357 if ( $this->asyncWrites && array_diff( $indexes, [ 0 ] ) && $method !==
'merge' ) {
360 $args = unserialize( serialize( $args ) );
363 foreach ( $indexes as $i ) {
364 $cache = $this->caches[$i];
366 if ( $i == 0 || !$this->asyncWrites ) {
368 $storeRes = $cache->proxyCall( $method, $arg0Sig, $resSig, $args, $this );
369 if ( $storeRes ===
false ) {
371 } elseif ( $res ===
null ) {
378 function () use ( $cache, $method, $arg0Sig, $resSig, $args ) {
379 $cache->proxyCall( $method, $arg0Sig, $resSig, $args, $this );
390class_alias( MultiWriteBagOStuff::class,
'MultiWriteBagOStuff' );
array $params
The job parameters.