MediaWiki  master
BagOStuff.php
Go to the documentation of this file.
1 <?php
33 
63 abstract 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 
95  public function __construct( array $params = [] ) {
96  $this->setLogger( $params['logger'] ?? new NullLogger() );
97  $this->asyncHandler = $params['asyncHandler'] ?? null;
98  }
99 
104  public function setLogger( LoggerInterface $logger ) {
105  $this->logger = $logger;
106  }
107 
111  public function setDebug( $enabled ) {
112  $this->debugMode = $enabled;
113  }
114 
128  final public function getWithSetCallback( $key, $ttl, $callback, $flags = 0 ) {
129  $value = $this->get( $key, $flags );
130 
131  if ( $value === false ) {
132  $value = $callback( $ttl );
133  if ( $value !== false && $ttl >= 0 ) {
134  $this->set( $key, $value, $ttl, $flags );
135  }
136  }
137 
138  return $value;
139  }
140 
154  abstract public function get( $key, $flags = 0 );
155 
165  abstract public function set( $key, $value, $exptime = 0, $flags = 0 );
166 
178  abstract public function delete( $key, $flags = 0 );
179 
189  abstract public function add( $key, $value, $exptime = 0, $flags = 0 );
190 
208  abstract public function merge(
209  $key,
210  callable $callback,
211  $exptime = 0,
212  $attempts = 10,
213  $flags = 0
214  );
215 
233  abstract public function changeTTL( $key, $exptime = 0, $flags = 0 );
234 
246  abstract public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' );
247 
254  abstract public function unlock( $key );
255 
272  final public function getScopedLock( $key, $timeout = 6, $expiry = 30, $rclass = '' ) {
273  $expiry = min( $expiry ?: INF, self::TTL_DAY );
274 
275  if ( !$this->lock( $key, $timeout, $expiry, $rclass ) ) {
276  return null;
277  }
278 
279  $lSince = $this->getCurrentTime(); // lock timestamp
280 
281  return new ScopedCallback( function () use ( $key, $lSince, $expiry ) {
282  $latency = 0.050; // latency skew (err towards keeping lock present)
283  $age = ( $this->getCurrentTime() - $lSince + $latency );
284  if ( ( $age + $latency ) >= $expiry ) {
285  $this->logger->warning(
286  "Lock for {key} held too long ({age} sec).",
287  [ 'key' => $key, 'age' => $age ]
288  );
289  return; // expired; it's not "safe" to delete the key
290  }
291  $this->unlock( $key );
292  } );
293  }
294 
305  abstract public function deleteObjectsExpiringBefore(
306  $timestamp,
307  callable $progress = null,
308  $limit = INF
309  );
310 
317  abstract public function getMulti( array $keys, $flags = 0 );
318 
332  abstract public function setMulti( array $data, $exptime = 0, $flags = 0 );
333 
346  abstract public function deleteMulti( array $keys, $flags = 0 );
347 
359  abstract public function changeTTLMulti( array $keys, $exptime, $flags = 0 );
360 
367  abstract public function incr( $key, $value = 1 );
368 
375  abstract public function decr( $key, $value = 1 );
376 
389  abstract public function incrWithInit( $key, $ttl, $value = 1, $init = 1 );
390 
396  abstract public function getLastError();
397 
402  abstract public function clearLastError();
403 
424  abstract public function addBusyCallback( callable $workCallback );
425 
434  abstract public function makeKeyInternal( $keyspace, $args );
435 
444  abstract public function makeGlobalKey( $class, ...$components );
445 
454  abstract public function makeKey( $class, ...$components );
455 
461  public function getQoS( $flag ) {
462  return $this->attrMap[$flag] ?? self::QOS_UNKNOWN;
463  }
464 
469  public function getSegmentationSize() {
470  return INF;
471  }
472 
477  public function getSegmentedValueMaxSize() {
478  return INF;
479  }
480 
487  final protected function mergeFlagMaps( array $bags ) {
488  $map = [];
489  foreach ( $bags as $bag ) {
490  foreach ( $bag->attrMap as $attr => $rank ) {
491  if ( isset( $map[$attr] ) ) {
492  $map[$attr] = min( $map[$attr], $rank );
493  } else {
494  $map[$attr] = $rank;
495  }
496  }
497  }
498 
499  return $map;
500  }
501 
507  public function getCurrentTime() {
508  return $this->wallClockOverride ?: microtime( true );
509  }
510 
516  public function setMockTime( &$time ) {
517  $this->wallClockOverride =& $time;
518  }
519 }
clearLastError()
Clear the "last error" registry.
getWithSetCallback( $key, $ttl, $callback, $flags=0)
Get an item with the given key, regenerating and setting it if not found.
Definition: BagOStuff.php:128
lock( $key, $timeout=6, $expiry=6, $rclass='')
Acquire an advisory lock on a key string.
deleteMulti(array $keys, $flags=0)
Batch deletion.
int [] $attrMap
Map of (ATTR_* class constant => QOS_* class constant)
Definition: BagOStuff.php:70
unlock( $key)
Release an advisory lock on a key string.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
const WRITE_PRUNE_SEGMENTS
Definition: BagOStuff.php:85
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
const WRITE_BACKGROUND
Definition: BagOStuff.php:86
$value
makeKey( $class,... $components)
Make a cache key, scoped to this instance&#39;s keyspace.
float null $wallClockOverride
Definition: BagOStuff.php:76
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1781
getSegmentationSize()
Definition: BagOStuff.php:469
getCurrentTime()
Definition: BagOStuff.php:507
if( $line===false) $args
Definition: cdb.php:64
getLastError()
Get the "last error" registered; clearLastError() should be called manually.
__construct(array $params=[])
Parameters include:
Definition: BagOStuff.php:95
bool $debugMode
Definition: BagOStuff.php:73
incr( $key, $value=1)
Increase stored value of $key by $value while preserving its TTL.
const READ_VERIFIED
Definition: BagOStuff.php:80
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on a key if it exists.
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF)
Delete all objects expiring before a certain date.
getMulti(array $keys, $flags=0)
Get an associative array containing the item for each of the keys that have items.
const WRITE_SYNC
Bitfield constants for set()/merge(); these are only advisory.
Definition: BagOStuff.php:82
$params
const READ_LATEST
Bitfield constants for get()/getMulti(); these are only advisory.
Definition: BagOStuff.php:79
setMockTime(&$time)
Definition: BagOStuff.php:516
makeKeyInternal( $keyspace, $args)
Construct a cache key.
mergeFlagMaps(array $bags)
Merge the flag maps of one or more BagOStuff objects into a "lowest common denominator" map...
Definition: BagOStuff.php:487
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:767
decr( $key, $value=1)
Decrease stored value of $key by $value while preserving its TTL.
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
makeGlobalKey( $class,... $components)
Make a global cache key.
getQoS( $flag)
Definition: BagOStuff.php:461
const WRITE_CACHE_ONLY
Definition: BagOStuff.php:83
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
const WRITE_ALLOW_SEGMENTS
Definition: BagOStuff.php:84
getScopedLock( $key, $timeout=6, $expiry=30, $rclass='')
Get a lightweight exclusive self-unlocking lock.
Definition: BagOStuff.php:272
LoggerInterface $logger
Definition: BagOStuff.php:65
setLogger(LoggerInterface $logger)
Definition: BagOStuff.php:104
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
setMulti(array $data, $exptime=0, $flags=0)
Batch insertion/replace.
addBusyCallback(callable $workCallback)
Let a callback be run to avoid wasting time on special blocking calls.
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple keys that exist.
Generic interface for object stores with key encoding methods.
getSegmentedValueMaxSize()
Definition: BagOStuff.php:477
callable null $asyncHandler
Definition: BagOStuff.php:68
setDebug( $enabled)
Definition: BagOStuff.php:111
incrWithInit( $key, $ttl, $value=1, $init=1)
Increase stored value of $key by $value while preserving its TTL.