MediaWiki  master
BagOStuff.php
Go to the documentation of this file.
1 <?php
29 use Psr\Log\LoggerAwareInterface;
30 use Psr\Log\LoggerInterface;
31 use Psr\Log\NullLogger;
34 use Wikimedia\ScopedCallback;
35 
66 abstract class BagOStuff implements
70  LoggerAwareInterface
71 {
73  protected $logger;
74 
76  protected $asyncHandler;
78  protected $attrMap = [];
79 
81  protected $debugMode = false;
82 
85 
87  public const READ_LATEST = 1; // if supported, avoid reading stale data due to replication
88  public const READ_VERIFIED = 2; // promise that the caller handles detection of staleness
90  public const WRITE_SYNC = 4; // if supported, block until the write is fully replicated
91  public const WRITE_CACHE_ONLY = 8; // only change state of the in-memory cache
92  public const WRITE_ALLOW_SEGMENTS = 16; // allow partitioning of the value if it is large
93  public const WRITE_PRUNE_SEGMENTS = 32; // delete all the segments if the value is partitioned
94  public const WRITE_BACKGROUND = 64; // if supported, do not block on completion until the next read
95 
104  public function __construct( array $params = [] ) {
105  $this->setLogger( $params['logger'] ?? new NullLogger() );
106  $this->asyncHandler = $params['asyncHandler'] ?? null;
107  }
108 
113  public function setLogger( LoggerInterface $logger ) {
114  $this->logger = $logger;
115  }
116 
121  public function getLogger() : LoggerInterface {
122  return $this->logger;
123  }
124 
128  public function setDebug( $enabled ) {
129  $this->debugMode = $enabled;
130  }
131 
145  final public function getWithSetCallback( $key, $exptime, $callback, $flags = 0 ) {
146  $value = $this->get( $key, $flags );
147 
148  if ( $value === false ) {
149  $value = $callback( $exptime );
150  if ( $value !== false && $exptime >= 0 ) {
151  $this->set( $key, $value, $exptime, $flags );
152  }
153  }
154 
155  return $value;
156  }
157 
171  abstract public function get( $key, $flags = 0 );
172 
182  abstract public function set( $key, $value, $exptime = 0, $flags = 0 );
183 
195  abstract public function delete( $key, $flags = 0 );
196 
206  abstract public function add( $key, $value, $exptime = 0, $flags = 0 );
207 
225  abstract public function merge(
226  $key,
227  callable $callback,
228  $exptime = 0,
229  $attempts = 10,
230  $flags = 0
231  );
232 
250  abstract public function changeTTL( $key, $exptime = 0, $flags = 0 );
251 
263  abstract public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' );
264 
271  abstract public function unlock( $key );
272 
289  final public function getScopedLock( $key, $timeout = 6, $expiry = 30, $rclass = '' ) {
290  $expiry = min( $expiry ?: INF, self::TTL_DAY );
291 
292  if ( !$this->lock( $key, $timeout, $expiry, $rclass ) ) {
293  return null;
294  }
295 
296  $lSince = $this->getCurrentTime(); // lock timestamp
297 
298  return new ScopedCallback( function () use ( $key, $lSince, $expiry ) {
299  $latency = 0.050; // latency skew (err towards keeping lock present)
300  $age = ( $this->getCurrentTime() - $lSince + $latency );
301  if ( ( $age + $latency ) >= $expiry ) {
302  $this->logger->warning(
303  "Lock for {key} held too long ({age} sec).",
304  [ 'key' => $key, 'age' => $age ]
305  );
306  return; // expired; it's not "safe" to delete the key
307  }
308  $this->unlock( $key );
309  } );
310  }
311 
322  abstract public function deleteObjectsExpiringBefore(
323  $timestamp,
324  callable $progress = null,
325  $limit = INF
326  );
327 
334  abstract public function getMulti( array $keys, $flags = 0 );
335 
349  abstract public function setMulti( array $data, $exptime = 0, $flags = 0 );
350 
363  abstract public function deleteMulti( array $keys, $flags = 0 );
364 
376  abstract public function changeTTLMulti( array $keys, $exptime, $flags = 0 );
377 
385  abstract public function incr( $key, $value = 1, $flags = 0 );
386 
394  abstract public function decr( $key, $value = 1, $flags = 0 );
395 
411  abstract public function incrWithInit( $key, $exptime, $value = 1, $init = null, $flags = 0 );
412 
418  abstract public function getLastError();
419 
424  abstract public function clearLastError();
425 
446  abstract public function addBusyCallback( callable $workCallback );
447 
456  abstract public function makeKeyInternal( $keyspace, $args );
457 
466  abstract public function makeGlobalKey( $class, ...$components );
467 
476  abstract public function makeKey( $class, ...$components );
477 
483  public function getQoS( $flag ) {
484  return $this->attrMap[$flag] ?? self::QOS_UNKNOWN;
485  }
486 
491  public function getSegmentationSize() {
492  return INF;
493  }
494 
499  public function getSegmentedValueMaxSize() {
500  return INF;
501  }
502 
509  final protected function fieldHasFlags( $field, $flags ) {
510  return ( ( $field & $flags ) === $flags );
511  }
512 
519  final protected function mergeFlagMaps( array $bags ) {
520  $map = [];
521  foreach ( $bags as $bag ) {
522  foreach ( $bag->attrMap as $attr => $rank ) {
523  if ( isset( $map[$attr] ) ) {
524  $map[$attr] = min( $map[$attr], $rank );
525  } else {
526  $map[$attr] = $rank;
527  }
528  }
529  }
530 
531  return $map;
532  }
533 
559  abstract public function setNewPreparedValues( array $valueByKey );
560 
566  public function getCurrentTime() {
567  return $this->wallClockOverride ?: microtime( true );
568  }
569 
575  public function setMockTime( &$time ) {
576  $this->wallClockOverride =& $time;
577  }
578 }
BagOStuff\getSegmentedValueMaxSize
getSegmentedValueMaxSize()
Definition: BagOStuff.php:499
BagOStuff\setNewPreparedValues
setNewPreparedValues(array $valueByKey)
Prepare values for storage and get their serialized sizes, or, estimate those sizes.
BagOStuff\getQoS
getQoS( $flag)
Definition: BagOStuff.php:483
BagOStuff\getLastError
getLastError()
Get the "last error" registered; clearLastError() should be called manually.
BagOStuff\add
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
BagOStuff\WRITE_SYNC
const WRITE_SYNC
Bitfield constants for set()/merge(); these are only advisory.
Definition: BagOStuff.php:90
BagOStuff\WRITE_ALLOW_SEGMENTS
const WRITE_ALLOW_SEGMENTS
Definition: BagOStuff.php:92
Wikimedia\LightweightObjectStore\ExpirationAwareness
Generic interface providing Time-To-Live constants for expirable object storage.
Definition: ExpirationAwareness.php:32
BagOStuff
Class representing a cache/ephemeral data store.
Definition: BagOStuff.php:71
BagOStuff\changeTTL
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on a key if it exists.
BagOStuff\$logger
LoggerInterface $logger
Definition: BagOStuff.php:73
BagOStuff\makeGlobalKey
makeGlobalKey( $class,... $components)
Make a global cache key.
BagOStuff\changeTTLMulti
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple keys that exist.
BagOStuff\setMockTime
setMockTime(&$time)
Definition: BagOStuff.php:575
BagOStuff\unlock
unlock( $key)
Release an advisory lock on a key string.
BagOStuff\clearLastError
clearLastError()
Clear the "last error" registry.
BagOStuff\decr
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
BagOStuff\incr
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
BagOStuff\setLogger
setLogger(LoggerInterface $logger)
Definition: BagOStuff.php:113
BagOStuff\$asyncHandler
callable null $asyncHandler
Definition: BagOStuff.php:76
BagOStuff\WRITE_BACKGROUND
const WRITE_BACKGROUND
Definition: BagOStuff.php:94
BagOStuff\READ_LATEST
const READ_LATEST
Bitfield constants for get()/getMulti(); these are only advisory.
Definition: BagOStuff.php:87
$args
if( $line===false) $args
Definition: mcc.php:124
BagOStuff\addBusyCallback
addBusyCallback(callable $workCallback)
Let a callback be run to avoid wasting time on special blocking calls.
BagOStuff\$wallClockOverride
float null $wallClockOverride
Definition: BagOStuff.php:84
BagOStuff\WRITE_PRUNE_SEGMENTS
const WRITE_PRUNE_SEGMENTS
Definition: BagOStuff.php:93
Wikimedia\LightweightObjectStore\StorageAwareness
Generic interface providing error code and quality-of-service constants for object stores.
Definition: StorageAwareness.php:32
BagOStuff\getWithSetCallback
getWithSetCallback( $key, $exptime, $callback, $flags=0)
Get an item with the given key, regenerating and setting it if not found.
Definition: BagOStuff.php:145
BagOStuff\mergeFlagMaps
mergeFlagMaps(array $bags)
Merge the flag maps of one or more BagOStuff objects into a "lowest common denominator" map.
Definition: BagOStuff.php:519
BagOStuff\__construct
__construct(array $params=[])
Parameters include:
Definition: BagOStuff.php:104
BagOStuff\getLogger
getLogger()
Definition: BagOStuff.php:121
BagOStuff\merge
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
BagOStuff\setMulti
setMulti(array $data, $exptime=0, $flags=0)
Batch insertion/replace.
BagOStuff\deleteMulti
deleteMulti(array $keys, $flags=0)
Batch deletion.
BagOStuff\makeKey
makeKey( $class,... $components)
Make a cache key, scoped to this instance's keyspace.
BagOStuff\incrWithInit
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.
BagOStuff\setDebug
setDebug( $enabled)
Definition: BagOStuff.php:128
BagOStuff\$debugMode
bool $debugMode
Definition: BagOStuff.php:81
BagOStuff\$attrMap
int[] $attrMap
Map of (ATTR_* class constant => QOS_* class constant)
Definition: BagOStuff.php:78
BagOStuff\READ_VERIFIED
const READ_VERIFIED
Definition: BagOStuff.php:88
BagOStuff\fieldHasFlags
fieldHasFlags( $field, $flags)
Definition: BagOStuff.php:509
BagOStuff\lock
lock( $key, $timeout=6, $expiry=6, $rclass='')
Acquire an advisory lock on a key string.
$keys
$keys
Definition: testCompression.php:72
BagOStuff\getCurrentTime
getCurrentTime()
Definition: BagOStuff.php:566
BagOStuff\deleteObjectsExpiringBefore
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF)
Delete all objects expiring before a certain date.
IStoreKeyEncoder
Generic interface for object stores with key encoding methods.
Definition: IStoreKeyEncoder.php:9
BagOStuff\makeKeyInternal
makeKeyInternal( $keyspace, $args)
Construct a cache key.
BagOStuff\getScopedLock
getScopedLock( $key, $timeout=6, $expiry=30, $rclass='')
Get a lightweight exclusive self-unlocking lock.
Definition: BagOStuff.php:289
BagOStuff\getSegmentationSize
getSegmentationSize()
Definition: BagOStuff.php:491
BagOStuff\getMulti
getMulti(array $keys, $flags=0)
Get an associative array containing the item for each of the keys that have items.
BagOStuff\WRITE_CACHE_ONLY
const WRITE_CACHE_ONLY
Definition: BagOStuff.php:91