23use Wikimedia\ObjectFactory\ObjectFactory;
46 private static $UPGRADE_TTL = 3600;
70 parent::__construct( $params );
72 if ( empty( $params[
'caches'] ) || !is_array( $params[
'caches'] ) ) {
73 throw new InvalidArgumentException(
74 __METHOD__ .
': "caches" parameter must be an array of caches'
79 foreach ( $params[
'caches'] as $cacheInfo ) {
81 $this->caches[] = $cacheInfo;
83 if ( !isset( $cacheInfo[
'args'] ) ) {
88 $cacheInfo[
'args'] = [ $cacheInfo ];
93 $this->caches[] = ObjectFactory::getObjectFromSpec( $cacheInfo );
99 $this->asyncWrites = (
100 isset( $params[
'replication'] ) &&
101 $params[
'replication'] ===
'async' &&
102 is_callable( $this->asyncHandler )
105 $this->cacheIndexes = array_keys( $this->caches );
108 public function get( $key, $flags = 0 ) {
109 $args = func_get_args();
115 return $this->callKeyMethodOnTierCache(
127 foreach ( $this->cacheIndexes as $i ) {
128 $value = $this->callKeyMethodOnTierCache(
135 if ( $value !==
false ) {
147 $this->callKeyWriteMethodOnTierCaches(
152 [ $key, $value, self::$UPGRADE_TTL ]
159 public function set( $key, $value, $exptime = 0, $flags = 0 ) {
160 return $this->callKeyWriteMethodOnTierCaches(
169 public function delete( $key, $flags = 0 ) {
170 return $this->callKeyWriteMethodOnTierCaches(
179 public function add( $key, $value, $exptime = 0, $flags = 0 ) {
181 $ok = $this->callKeyMethodOnTierCache(
193 $okSecondaries = $this->callKeyWriteMethodOnTierCaches(
194 array_slice( $this->cacheIndexes, 1 ),
198 [ $key, $value, $exptime, $flags ]
200 if ( $okSecondaries ===
false ) {
208 public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
209 return $this->callKeyWriteMethodOnTierCaches(
218 public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
219 return $this->callKeyWriteMethodOnTierCaches(
228 public function lock( $key, $timeout = 6, $exptime = 6, $rclass =
'' ) {
230 return $this->callKeyMethodOnTierCache(
241 return $this->callKeyMethodOnTierCache(
252 callable $progress =
null,
257 foreach ( $this->caches as
$cache ) {
258 if (
$cache->deleteObjectsExpiringBefore( $timestamp, $progress, $limit, $tag ) ) {
269 foreach (
$keys as $key ) {
270 $val = $this->
get( $key, $flags );
271 if ( $val !==
false ) {
279 public function setMulti( array $valueByKey, $exptime = 0, $flags = 0 ) {
280 return $this->callKeyWriteMethodOnTierCaches(
290 return $this->callKeyWriteMethodOnTierCaches(
300 return $this->callKeyWriteMethodOnTierCaches(
309 public function incr( $key, $value = 1, $flags = 0 ) {
310 return $this->callKeyWriteMethodOnTierCaches(
319 public function decr( $key, $value = 1, $flags = 0 ) {
320 return $this->callKeyWriteMethodOnTierCaches(
329 public function incrWithInit( $key, $exptime, $step = 1, $init =
null, $flags = 0 ) {
330 return $this->callKeyWriteMethodOnTierCaches(
343 public function makeKey( $collection, ...$components ) {
357 $this->caches[0]->addBusyCallback( $workCallback );
361 return $this->callKeyMethodOnTierCache(
371 parent::setMockTime( $time );
372 foreach ( $this->caches as
$cache ) {
373 $cache->setMockTime( $time );
387 private function callKeyMethodOnTierCache( $index, $method, $arg0Sig, $rvSig, array
$args ) {
388 return $this->caches[$index]->proxyCall( $method, $arg0Sig, $rvSig,
$args, $this );
401 private function callKeyWriteMethodOnTierCaches(
410 if ( $this->asyncWrites && array_diff( $indexes, [ 0 ] ) && $method !==
'merge' ) {
416 foreach ( $indexes as $i ) {
417 $cache = $this->caches[$i];
419 if ( $i == 0 || !$this->asyncWrites ) {
421 $storeRes =
$cache->proxyCall( $method, $arg0Sig, $resSig,
$args, $this );
422 if ( $storeRes ===
false ) {
424 } elseif (
$res ===
null ) {
431 function () use (
$cache, $method, $arg0Sig, $resSig,
$args ) {
432 $cache->proxyCall( $method, $arg0Sig, $resSig,
$args, $this );
unserialize( $serialized)
Class representing a cache/ephemeral data store.
mergeFlagMaps(array $bags)
Merge the flag maps of one or more BagOStuff objects into a "lowest common denominator" map.
genericKeyFromComponents(... $components)
At a minimum, there must be a keyspace and collection name component.
string $keyspace
Default keyspace; used by makeKey()
fieldHasFlags( $field, $flags)
callable null $asyncHandler
A cache class that replicates all writes to multiple child caches.
deleteMulti(array $keys, $flags=0)
Delete a batch of items.
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple items.
makeKey( $collection,... $components)
Make a cache key for the global keyspace and given components.
incrWithInit( $key, $exptime, $step=1, $init=null, $flags=0)
Increase the value of the given key (no TTL change) if it exists or create it otherwise.
int[] $cacheIndexes
List of all backing cache indexes.
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
makeGlobalKey( $collection,... $components)
Make a cache key for the default keyspace and given components.
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on an item.
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF, string $tag=null)
Delete all objects expiring before a certain date.
BagOStuff[] $caches
Backing cache stores in order of highest to lowest tier.
bool $asyncWrites
Use async secondary writes.
setMulti(array $valueByKey, $exptime=0, $flags=0)
Set a batch of items.
lock( $key, $timeout=6, $exptime=6, $rclass='')
Acquire an advisory lock on a key string, exclusive to the caller.
convertGenericKey( $key)
Convert a "generic" reversible cache key into one for this cache.
makeKeyInternal( $keyspace, $components)
Make a cache key for the given keyspace and components.
setNewPreparedValues(array $valueByKey)
Stage a set of new key values for storage and estimate the amount of bytes needed.
getMulti(array $keys, $flags=0)
Get a batch of items.
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
addBusyCallback(callable $workCallback)
Let a callback be run to avoid wasting time on special blocking calls.
unlock( $key)
Release an advisory lock on a key string.