MediaWiki REL1_34
BagOStuff.php
Go to the documentation of this file.
1<?php
29use Psr\Log\LoggerAwareInterface;
30use Psr\Log\LoggerInterface;
31use Psr\Log\NullLogger;
32use Wikimedia\ScopedCallback;
33
63abstract class BagOStuff implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInterface {
65 protected $logger;
66
68 protected $asyncHandler;
70 protected $attrMap = [];
71
73 protected $debugMode = false;
74
77
79 const READ_LATEST = 1; // if supported, avoid reading stale data due to replication
80 const READ_VERIFIED = 2; // promise that the caller handles detection of staleness
82 const WRITE_SYNC = 4; // if supported, block until the write is fully replicated
83 const WRITE_CACHE_ONLY = 8; // only change state of the in-memory cache
84 const WRITE_ALLOW_SEGMENTS = 16; // allow partitioning of the value if it is large
85 const WRITE_PRUNE_SEGMENTS = 32; // delete all the segments if the value is partitioned
86 const WRITE_BACKGROUND = 64; // if supported, do not block on completion until the next read
87
96 public function __construct( array $params = [] ) {
97 $this->setLogger( $params['logger'] ?? new NullLogger() );
98 $this->asyncHandler = $params['asyncHandler'] ?? null;
99 }
100
105 public function setLogger( LoggerInterface $logger ) {
106 $this->logger = $logger;
107 }
108
112 public function setDebug( $enabled ) {
113 $this->debugMode = $enabled;
114 }
115
129 final public function getWithSetCallback( $key, $ttl, $callback, $flags = 0 ) {
130 $value = $this->get( $key, $flags );
131
132 if ( $value === false ) {
133 $value = $callback( $ttl );
134 if ( $value !== false && $ttl >= 0 ) {
135 $this->set( $key, $value, $ttl, $flags );
136 }
137 }
138
139 return $value;
140 }
141
155 abstract public function get( $key, $flags = 0 );
156
166 abstract public function set( $key, $value, $exptime = 0, $flags = 0 );
167
179 abstract public function delete( $key, $flags = 0 );
180
190 abstract public function add( $key, $value, $exptime = 0, $flags = 0 );
191
209 abstract public function merge(
210 $key,
211 callable $callback,
212 $exptime = 0,
213 $attempts = 10,
214 $flags = 0
215 );
216
234 abstract public function changeTTL( $key, $exptime = 0, $flags = 0 );
235
247 abstract public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' );
248
255 abstract public function unlock( $key );
256
273 final public function getScopedLock( $key, $timeout = 6, $expiry = 30, $rclass = '' ) {
274 $expiry = min( $expiry ?: INF, self::TTL_DAY );
275
276 if ( !$this->lock( $key, $timeout, $expiry, $rclass ) ) {
277 return null;
278 }
279
280 $lSince = $this->getCurrentTime(); // lock timestamp
281
282 return new ScopedCallback( function () use ( $key, $lSince, $expiry ) {
283 $latency = 0.050; // latency skew (err towards keeping lock present)
284 $age = ( $this->getCurrentTime() - $lSince + $latency );
285 if ( ( $age + $latency ) >= $expiry ) {
286 $this->logger->warning(
287 "Lock for {key} held too long ({age} sec).",
288 [ 'key' => $key, 'age' => $age ]
289 );
290 return; // expired; it's not "safe" to delete the key
291 }
292 $this->unlock( $key );
293 } );
294 }
295
306 abstract public function deleteObjectsExpiringBefore(
307 $timestamp,
308 callable $progress = null,
309 $limit = INF
310 );
311
318 abstract public function getMulti( array $keys, $flags = 0 );
319
333 abstract public function setMulti( array $data, $exptime = 0, $flags = 0 );
334
347 abstract public function deleteMulti( array $keys, $flags = 0 );
348
360 abstract public function changeTTLMulti( array $keys, $exptime, $flags = 0 );
361
369 abstract public function incr( $key, $value = 1, $flags = 0 );
370
378 abstract public function decr( $key, $value = 1, $flags = 0 );
379
395 abstract public function incrWithInit( $key, $exptime, $value = 1, $init = null, $flags = 0 );
396
402 abstract public function getLastError();
403
408 abstract public function clearLastError();
409
430 abstract public function addBusyCallback( callable $workCallback );
431
440 abstract public function makeKeyInternal( $keyspace, $args );
441
450 abstract public function makeGlobalKey( $class, ...$components );
451
460 abstract public function makeKey( $class, ...$components );
461
467 public function getQoS( $flag ) {
468 return $this->attrMap[$flag] ?? self::QOS_UNKNOWN;
469 }
470
475 public function getSegmentationSize() {
476 return INF;
477 }
478
483 public function getSegmentedValueMaxSize() {
484 return INF;
485 }
486
493 final protected function fieldHasFlags( $field, $flags ) {
494 return ( ( $field & $flags ) === $flags );
495 }
496
503 final protected function mergeFlagMaps( array $bags ) {
504 $map = [];
505 foreach ( $bags as $bag ) {
506 foreach ( $bag->attrMap as $attr => $rank ) {
507 if ( isset( $map[$attr] ) ) {
508 $map[$attr] = min( $map[$attr], $rank );
509 } else {
510 $map[$attr] = $rank;
511 }
512 }
513 }
514
515 return $map;
516 }
517
523 public function getCurrentTime() {
524 return $this->wallClockOverride ?: microtime( true );
525 }
526
532 public function setMockTime( &$time ) {
533 $this->wallClockOverride =& $time;
534 }
535}
if( $line===false) $args
Definition cdb.php:64
Class representing a cache/ephemeral data store.
Definition BagOStuff.php:63
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
int[] $attrMap
Map of (ATTR_* class constant => QOS_* class constant)
Definition BagOStuff.php:70
getWithSetCallback( $key, $ttl, $callback, $flags=0)
Get an item with the given key, regenerating and setting it if not found.
__construct(array $params=[])
Parameters include:
Definition BagOStuff.php:96
getScopedLock( $key, $timeout=6, $expiry=30, $rclass='')
Get a lightweight exclusive self-unlocking lock.
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
unlock( $key)
Release an advisory lock on a key string.
lock( $key, $timeout=6, $expiry=6, $rclass='')
Acquire an advisory lock on a key string.
getSegmentedValueMaxSize()
deleteMulti(array $keys, $flags=0)
Batch deletion.
const WRITE_ALLOW_SEGMENTS
Definition BagOStuff.php:84
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
getMulti(array $keys, $flags=0)
Get an associative array containing the item for each of the keys that have items.
makeKey( $class,... $components)
Make a cache key, scoped to this instance's keyspace.
setDebug( $enabled)
float null $wallClockOverride
Definition BagOStuff.php:76
getQoS( $flag)
const READ_LATEST
Bitfield constants for get()/getMulti(); these are only advisory.
Definition BagOStuff.php:79
const READ_VERIFIED
Definition BagOStuff.php:80
makeGlobalKey( $class,... $components)
Make a global cache key.
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.
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on a key if it exists.
const WRITE_PRUNE_SEGMENTS
Definition BagOStuff.php:85
setLogger(LoggerInterface $logger)
setMulti(array $data, $exptime=0, $flags=0)
Batch insertion/replace.
setMockTime(&$time)
const WRITE_SYNC
Bitfield constants for set()/merge(); these are only advisory.
Definition BagOStuff.php:82
mergeFlagMaps(array $bags)
Merge the flag maps of one or more BagOStuff objects into a "lowest common denominator" map.
getLastError()
Get the "last error" registered; clearLastError() should be called manually.
bool $debugMode
Definition BagOStuff.php:73
getSegmentationSize()
LoggerInterface $logger
Definition BagOStuff.php:65
clearLastError()
Clear the "last error" registry.
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple keys that exist.
addBusyCallback(callable $workCallback)
Let a callback be run to avoid wasting time on special blocking calls.
makeKeyInternal( $keyspace, $args)
Construct a cache key.
const WRITE_CACHE_ONLY
Definition BagOStuff.php:83
fieldHasFlags( $field, $flags)
callable null $asyncHandler
Definition BagOStuff.php:68
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
const WRITE_BACKGROUND
Definition BagOStuff.php:86
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF)
Delete all objects expiring before a certain date.
Generic interface for lightweight expiring object stores.
Generic interface for object stores with key encoding methods.