MediaWiki  1.23.8
BagOStuff.php
Go to the documentation of this file.
1 <?php
43 abstract class BagOStuff {
44  private $debugMode = false;
45 
47 
49  const ERR_NONE = 0; // no error
50  const ERR_NO_RESPONSE = 1; // no response
51  const ERR_UNREACHABLE = 2; // can't connect
52  const ERR_UNEXPECTED = 3; // response gave some error
53 
57  public function setDebug( $bool ) {
58  $this->debugMode = $bool;
59  }
60 
61  /* *** THE GUTS OF THE OPERATION *** */
62  /* Override these with functional things in subclasses */
63 
70  abstract public function get( $key, &$casToken = null );
71 
79  abstract public function set( $key, $value, $exptime = 0 );
80 
89  abstract public function cas( $casToken, $key, $value, $exptime = 0 );
90 
97  abstract public function delete( $key, $time = 0 );
98 
110  public function merge( $key, closure $callback, $exptime = 0, $attempts = 10 ) {
111  return $this->mergeViaCas( $key, $callback, $exptime, $attempts );
112  }
113 
123  protected function mergeViaCas( $key, closure $callback, $exptime = 0, $attempts = 10 ) {
124  do {
125  $casToken = null; // passed by reference
126  $currentValue = $this->get( $key, $casToken ); // get the old value
127  $value = $callback( $this, $key, $currentValue ); // derive the new value
128 
129  if ( $value === false ) {
130  $success = true; // do nothing
131  } elseif ( $currentValue === false ) {
132  // Try to create the key, failing if it gets created in the meantime
133  $success = $this->add( $key, $value, $exptime );
134  } else {
135  // Try to update the key, failing if it gets changed in the meantime
136  $success = $this->cas( $casToken, $key, $value, $exptime );
137  }
138  } while ( !$success && --$attempts );
139 
140  return $success;
141  }
142 
152  protected function mergeViaLock( $key, closure $callback, $exptime = 0, $attempts = 10 ) {
153  if ( !$this->lock( $key, 6 ) ) {
154  return false;
155  }
156 
157  $currentValue = $this->get( $key ); // get the old value
158  $value = $callback( $this, $key, $currentValue ); // derive the new value
159 
160  if ( $value === false ) {
161  $success = true; // do nothing
162  } else {
163  $success = $this->set( $key, $value, $exptime ); // set the new value
164  }
165 
166  if ( !$this->unlock( $key ) ) {
167  // this should never happen
168  trigger_error( "Could not release lock for key '$key'." );
169  }
170 
171  return $success;
172  }
173 
179  public function lock( $key, $timeout = 6 ) {
180  $this->clearLastError();
181  $timestamp = microtime( true ); // starting UNIX timestamp
182  if ( $this->add( "{$key}:lock", 1, $timeout ) ) {
183  return true;
184  } elseif ( $this->getLastError() ) {
185  return false;
186  }
187 
188  $uRTT = ceil( 1e6 * ( microtime( true ) - $timestamp ) ); // estimate RTT (us)
189  $sleep = 2 * $uRTT; // rough time to do get()+set()
190 
191  $locked = false; // lock acquired
192  $attempts = 0; // failed attempts
193  do {
194  if ( ++$attempts >= 3 && $sleep <= 1e6 ) {
195  // Exponentially back off after failed attempts to avoid network spam.
196  // About 2*$uRTT*(2^n-1) us of "sleep" happen for the next n attempts.
197  $sleep *= 2;
198  }
199  usleep( $sleep ); // back off
200  $this->clearLastError();
201  $locked = $this->add( "{$key}:lock", 1, $timeout );
202  if ( $this->getLastError() ) {
203  return false;
204  }
205  } while ( !$locked );
206 
207  return $locked;
208  }
209 
214  public function unlock( $key ) {
215  return $this->delete( "{$key}:lock" );
216  }
217 
227  public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) {
228  // stub
229  return false;
230  }
231 
232  /* *** Emulated functions *** */
233 
239  public function getMulti( array $keys ) {
240  $res = array();
241  foreach ( $keys as $key ) {
242  $val = $this->get( $key );
243  if ( $val !== false ) {
244  $res[$key] = $val;
245  }
246  }
247  return $res;
248  }
249 
256  public function add( $key, $value, $exptime = 0 ) {
257  if ( $this->get( $key ) === false ) {
258  return $this->set( $key, $value, $exptime );
259  }
260  return false; // key already set
261  }
262 
270  public function replace( $key, $value, $exptime = 0 ) {
271  wfDeprecated( __METHOD__, '1.23' );
272  if ( $this->get( $key ) !== false ) {
273  return $this->set( $key, $value, $exptime );
274  }
275  return false; // key not already set
276  }
277 
284  public function incr( $key, $value = 1 ) {
285  if ( !$this->lock( $key ) ) {
286  return false;
287  }
288  $n = $this->get( $key );
289  if ( $this->isInteger( $n ) ) { // key exists?
290  $n += intval( $value );
291  $this->set( $key, max( 0, $n ) ); // exptime?
292  } else {
293  $n = false;
294  }
295  $this->unlock( $key );
296 
297  return $n;
298  }
299 
306  public function decr( $key, $value = 1 ) {
307  return $this->incr( $key, - $value );
308  }
309 
315  public function getLastError() {
316  return $this->lastError;
317  }
318 
323  public function clearLastError() {
324  $this->lastError = self::ERR_NONE;
325  }
326 
332  protected function setLastError( $err ) {
333  $this->lastError = $err;
334  }
335 
339  public function debug( $text ) {
340  if ( $this->debugMode ) {
341  $class = get_class( $this );
342  wfDebug( "$class debug: $text\n" );
343  }
344  }
345 
351  protected function convertExpiry( $exptime ) {
352  if ( ( $exptime != 0 ) && ( $exptime < 86400 * 3650 /* 10 years */ ) ) {
353  return time() + $exptime;
354  } else {
355  return $exptime;
356  }
357  }
358 
366  protected function convertToRelative( $exptime ) {
367  if ( $exptime >= 86400 * 3650 /* 10 years */ ) {
368  $exptime -= time();
369  if ( $exptime <= 0 ) {
370  $exptime = 1;
371  }
372  return $exptime;
373  } else {
374  return $exptime;
375  }
376  }
377 
384  protected function isInteger( $value ) {
385  return ( is_int( $value ) || ctype_digit( $value ) );
386  }
387 }
BagOStuff\isInteger
isInteger( $value)
Check if a value is an integer.
Definition: BagOStuff.php:384
BagOStuff\add
add( $key, $value, $exptime=0)
Definition: BagOStuff.php:256
$time
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1358
BagOStuff\decr
decr( $key, $value=1)
Decrease stored value of $key by $value while preserving its TTL.
Definition: BagOStuff.php:306
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
BagOStuff\ERR_UNREACHABLE
const ERR_UNREACHABLE
Definition: BagOStuff.php:51
BagOStuff\getLastError
getLastError()
Get the "last error" registered; clearLastError() should be called manually.
Definition: BagOStuff.php:315
$timestamp
if( $limit) $timestamp
Definition: importImages.php:104
BagOStuff\deleteObjectsExpiringBefore
deleteObjectsExpiringBefore( $date, $progressCallback=false)
Delete all objects expiring before a certain date.
Definition: BagOStuff.php:227
BagOStuff\convertExpiry
convertExpiry( $exptime)
Convert an optionally relative time to an absolute time.
Definition: BagOStuff.php:351
$n
$n
Definition: RandomTest.php:76
BagOStuff\debug
debug( $text)
Definition: BagOStuff.php:339
BagOStuff\replace
replace( $key, $value, $exptime=0)
Definition: BagOStuff.php:270
BagOStuff
interface is intended to be more or less compatible with the PHP memcached client.
Definition: BagOStuff.php:43
BagOStuff\setDebug
setDebug( $bool)
Definition: BagOStuff.php:57
$sleep
$sleep
Definition: importImages.php:93
BagOStuff\ERR_NONE
const ERR_NONE
Possible values for getLastError()
Definition: BagOStuff.php:49
BagOStuff\unlock
unlock( $key)
Definition: BagOStuff.php:214
BagOStuff\clearLastError
clearLastError()
Clear the "last error" registry.
Definition: BagOStuff.php:323
$success
$success
Definition: Utf8Test.php:91
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1127
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
BagOStuff\merge
merge( $key, closure $callback, $exptime=0, $attempts=10)
Merge changes into the existing cache value (possibly creating a new one).
Definition: BagOStuff.php:110
BagOStuff\$lastError
$lastError
Definition: BagOStuff.php:46
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:933
$value
$value
Definition: styleTest.css.php:45
BagOStuff\incr
incr( $key, $value=1)
Increase stored value of $key by $value while preserving its TTL.
Definition: BagOStuff.php:284
as
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
BagOStuff\$debugMode
$debugMode
Definition: BagOStuff.php:44
BagOStuff\getMulti
getMulti(array $keys)
Get an associative array containing the item for each of the keys that have items.
Definition: BagOStuff.php:239
$keys
$keys
Definition: testCompression.php:63
BagOStuff\cas
cas( $casToken, $key, $value, $exptime=0)
Check and set an item.
BagOStuff\lock
lock( $key, $timeout=6)
Definition: BagOStuff.php:179
BagOStuff\mergeViaLock
mergeViaLock( $key, closure $callback, $exptime=0, $attempts=10)
Definition: BagOStuff.php:152
BagOStuff\mergeViaCas
mergeViaCas( $key, closure $callback, $exptime=0, $attempts=10)
Definition: BagOStuff.php:123
BagOStuff\ERR_NO_RESPONSE
const ERR_NO_RESPONSE
Definition: BagOStuff.php:50
BagOStuff\setLastError
setLastError( $err)
Set the "last error" registry.
Definition: BagOStuff.php:332
$res
$res
Definition: database.txt:21
BagOStuff\ERR_UNEXPECTED
const ERR_UNEXPECTED
Definition: BagOStuff.php:52
BagOStuff\convertToRelative
convertToRelative( $exptime)
Convert an optionally absolute expiry time to a relative time.
Definition: BagOStuff.php:366