Go to the documentation of this file.
29 use Psr\Log\LoggerAwareInterface;
30 use Psr\Log\LoggerInterface;
31 use Psr\Log\NullLogger;
34 use Wikimedia\ScopedCallback;
100 protected const GLOBAL_KEYSPACE =
'global';
102 protected const GLOBAL_PREFIX =
'global:';
104 protected const GLOBAL_PREFIX_LEN = 7;
107 protected const ARG0_KEY = 0;
109 protected const ARG0_KEYARR = 1;
111 protected const ARG0_KEYMAP = 2;
113 protected const ARG0_NONKEY = 3;
116 protected const RES_KEYMAP = 0;
118 protected const RES_NONKEY = 1;
132 $this->keyspace = $params[
'keyspace'] ??
'local';
133 $this->
setLogger( $params[
'logger'] ??
new NullLogger() );
134 $this->asyncHandler = $params[
'asyncHandler'] ??
null;
157 $this->debugMode = $enabled;
174 $value = $this->
get( $key, $flags );
176 if ( $value ===
false ) {
177 $value = $callback( $exptime );
178 if ( $value !==
false && $exptime >= 0 ) {
179 $this->
set( $key, $value, $exptime, $flags );
199 abstract public function get( $key, $flags = 0 );
210 abstract public function set( $key, $value, $exptime = 0, $flags = 0 );
223 abstract public function delete( $key, $flags = 0 );
234 abstract public function add( $key, $value, $exptime = 0, $flags = 0 );
278 abstract public function changeTTL( $key, $exptime = 0, $flags = 0 );
291 abstract public function lock( $key, $timeout = 6, $expiry = 6, $rclass =
'' );
317 final public function getScopedLock( $key, $timeout = 6, $expiry = 30, $rclass =
'' ) {
318 $expiry = min( $expiry ?: INF, self::TTL_DAY );
320 if ( !$this->
lock( $key, $timeout, $expiry, $rclass ) ) {
326 return new ScopedCallback(
function () use ( $key, $lSince, $expiry ) {
329 if ( ( $age + $latency ) >= $expiry ) {
330 $this->logger->warning(
331 "Lock for {key} held too long ({age} sec).",
332 [
'key' => $key,
'age' => $age ]
352 callable $progress =
null,
378 abstract public function setMulti( array $valueByKey, $exptime = 0, $flags = 0 );
415 abstract public function incr( $key, $value = 1, $flags = 0 );
425 abstract public function decr( $key, $value = 1, $flags = 0 );
442 abstract public function incrWithInit( $key, $exptime, $value = 1, $init =
null, $flags = 0 );
512 abstract public function makeKey( $class, ...$components );
522 return ( strncmp( $key, self::GLOBAL_PREFIX, self::GLOBAL_PREFIX_LEN ) === 0 );
531 return $this->attrMap[$flag] ?? self::QOS_UNKNOWN;
557 return ( ( $field & $flags ) === $flags );
568 foreach ( $bags as $bag ) {
569 foreach ( $bag->attrMap as $attr => $rank ) {
570 if ( isset( $map[$attr] ) ) {
571 $map[$attr] = min( $map[$attr], $rank );
616 if ( count( $components ) < 2 ) {
617 throw new InvalidArgumentException(
"Missing keyspace or collection name" );
621 foreach ( $components as $component ) {
626 $key .= strtr( $component, [
'%' =>
'%25',
':' =>
'%3A' ] );
643 return str_replace( [
'%3A',
'%25' ], [
':',
'%' ], explode(
':', $key ) );
665 protected function proxyCall( $method, $arg0Sig, $resSig, array $genericArgs ) {
667 $storeArgs = $genericArgs;
668 switch ( $arg0Sig ) {
672 case self::ARG0_KEYARR:
673 foreach ( $genericArgs[0] as $i => $genericKey ) {
677 case self::ARG0_KEYMAP:
679 foreach ( $genericArgs[0] as $genericKey => $v ) {
686 $storeRes = $this->$method( ...$storeArgs );
689 if ( $resSig === self::RES_KEYMAP ) {
691 $genericKeyByStoreKey = array_combine( $storeArgs[0], $genericArgs[0] );
694 foreach ( $storeRes as $storeKey => $value ) {
695 $genericRes[$genericKeyByStoreKey[$storeKey]] = $value;
698 $genericRes = $storeRes;
710 return $this->wallClockOverride ?: microtime(
true );
719 $this->wallClockOverride =& $time;
getSegmentedValueMaxSize()
setNewPreparedValues(array $valueByKey)
Make a "generic" reversible cache key from the given components.
getLastError()
Get the "last error" registered; clearLastError() should be called manually.
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
const WRITE_SYNC
Bitfield constants for set()/merge(); these are only advisory.
const WRITE_ALLOW_SEGMENTS
Class representing a cache/ephemeral data store.
genericKeyFromComponents(... $components)
At a minimum, there must be a keyspace and collection name component.
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on a key if it exists.
componentsFromGenericKey( $key)
Extract the components from a "generic" reversible cache key.
convertGenericKey( $key)
Convert a "generic" reversible cache key into one for this cache.
makeGlobalKey( $class,... $components)
Make a cache key for the default keyspace and given components.
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple keys that exist.
isKeyGlobal( $key)
Check whether a cache key is in the global keyspace.
unlock( $key)
Release an advisory lock on a key string.
clearLastError()
Clear the "last error" registry.
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
setLogger(LoggerInterface $logger)
callable null $asyncHandler
proxyCall( $method, $arg0Sig, $resSig, array $genericArgs)
Call a method on behalf of wrapper BagOStuff instance that uses "generic" keys.
const READ_LATEST
Bitfield constants for get()/getMulti(); these are only advisory.
addBusyCallback(callable $workCallback)
Let a callback be run to avoid wasting time on special blocking calls.
float null $wallClockOverride
const WRITE_PRUNE_SEGMENTS
getWithSetCallback( $key, $exptime, $callback, $flags=0)
Get an item with the given key, regenerating and setting it if not found.
mergeFlagMaps(array $bags)
Merge the flag maps of one or more BagOStuff objects into a "lowest common denominator" map.
__construct(array $params=[])
Parameters include:
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
deleteMulti(array $keys, $flags=0)
Batch deletion.
makeKey( $class,... $components)
Make a cache key for the global keyspace and given components.
incrWithInit( $key, $exptime, $value=1, $init=null, $flags=0)
Increase the value of the given key (no TTL change) if it exists or create it otherwise.
makeKeyInternal( $keyspace, $components)
Make a cache key for the given keyspace and components.
setMulti(array $valueByKey, $exptime=0, $flags=0)
Batch insertion/replace.
bool $debugMode
Whether to send debug log entries to the SPI logger instance.
int[] $attrMap
Map of (ATTR_* class constant => QOS_* class constant)
fieldHasFlags( $field, $flags)
lock( $key, $timeout=6, $expiry=6, $rclass='')
Acquire an advisory lock on a key string.
string $keyspace
Default keyspace; used by makeKey()
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF)
Delete all objects expiring before a certain date.
Generic interface for object stores with key encoding methods.
getScopedLock( $key, $timeout=6, $expiry=30, $rclass='')
Get a lightweight exclusive self-unlocking lock.
getMulti(array $keys, $flags=0)
Get an associative array containing the item for each of the keys that have items.