diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2014-12-27 15:41:37 +0100 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2014-12-31 11:43:28 +0100 |
commit | c1f9b1f7b1b77776192048005dcc66dcf3df2bfb (patch) | |
tree | 2b38796e738dd74cb42ecd9bfd151803108386bc /includes/objectcache/BagOStuff.php | |
parent | b88ab0086858470dd1f644e64cb4e4f62bb2be9b (diff) |
Update to MediaWiki 1.24.1
Diffstat (limited to 'includes/objectcache/BagOStuff.php')
-rw-r--r-- | includes/objectcache/BagOStuff.php | 180 |
1 files changed, 121 insertions, 59 deletions
diff --git a/includes/objectcache/BagOStuff.php b/includes/objectcache/BagOStuff.php index 857943ee..1978c3ea 100644 --- a/includes/objectcache/BagOStuff.php +++ b/includes/objectcache/BagOStuff.php @@ -3,7 +3,7 @@ * Classes to cache objects in PHP accelerators, SQL database or DBA files * * Copyright © 2003-2004 Brion Vibber <brion@pobox.com> - * http://www.mediawiki.org/ + * https://www.mediawiki.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,8 +43,16 @@ abstract class BagOStuff { private $debugMode = false; + protected $lastError = self::ERR_NONE; + + /** Possible values for getLastError() */ + const ERR_NONE = 0; // no error + const ERR_NO_RESPONSE = 1; // no response + const ERR_UNREACHABLE = 2; // can't connect + const ERR_UNEXPECTED = 3; // response gave some error + /** - * @param $bool bool + * @param bool $bool */ public function setDebug( $bool ) { $this->debugMode = $bool; @@ -55,34 +63,34 @@ abstract class BagOStuff { /** * Get an item with the given key. Returns false if it does not exist. - * @param $key string - * @param $casToken[optional] mixed + * @param string $key + * @param mixed $casToken [optional] * @return mixed Returns false on failure */ abstract public function get( $key, &$casToken = null ); /** * Set an item. - * @param $key string - * @param $value mixed + * @param string $key + * @param mixed $value * @param int $exptime Either an interval in seconds or a unix timestamp for expiry - * @return bool success + * @return bool Success */ abstract public function set( $key, $value, $exptime = 0 ); /** * Check and set an item. - * @param $casToken mixed - * @param $key string - * @param $value mixed + * @param mixed $casToken + * @param string $key + * @param mixed $value * @param int $exptime Either an interval in seconds or a unix timestamp for expiry - * @return bool success + * @return bool Success */ abstract public function cas( $casToken, $key, $value, $exptime = 0 ); /** * Delete an item. - * @param $key string + * @param string $key * @param int $time Amount of time to delay the operation (mostly memcached-specific) * @return bool True if the item was deleted or not found, false on failure */ @@ -93,26 +101,26 @@ abstract class BagOStuff { * The callback function returns the new value given the current value (possibly false), * and takes the arguments: (this BagOStuff object, cache key, current value). * - * @param $key string - * @param $callback closure Callback method to be executed + * @param string $key + * @param Closure $callback Callback method to be executed * @param int $exptime Either an interval in seconds or a unix timestamp for expiry * @param int $attempts The amount of times to attempt a merge in case of failure - * @return bool success + * @return bool Success */ - public function merge( $key, closure $callback, $exptime = 0, $attempts = 10 ) { + public function merge( $key, Closure $callback, $exptime = 0, $attempts = 10 ) { return $this->mergeViaCas( $key, $callback, $exptime, $attempts ); } /** * @see BagOStuff::merge() * - * @param $key string - * @param $callback closure Callback method to be executed + * @param string $key + * @param Closure $callback Callback method to be executed * @param int $exptime Either an interval in seconds or a unix timestamp for expiry * @param int $attempts The amount of times to attempt a merge in case of failure - * @return bool success + * @return bool Success */ - protected function mergeViaCas( $key, closure $callback, $exptime = 0, $attempts = 10 ) { + protected function mergeViaCas( $key, Closure $callback, $exptime = 0, $attempts = 10 ) { do { $casToken = null; // passed by reference $currentValue = $this->get( $key, $casToken ); // get the old value @@ -135,14 +143,14 @@ abstract class BagOStuff { /** * @see BagOStuff::merge() * - * @param $key string - * @param $callback closure Callback method to be executed + * @param string $key + * @param Closure $callback Callback method to be executed * @param int $exptime Either an interval in seconds or a unix timestamp for expiry * @param int $attempts The amount of times to attempt a merge in case of failure - * @return bool success + * @return bool Success */ - protected function mergeViaLock( $key, closure $callback, $exptime = 0, $attempts = 10 ) { - if ( !$this->lock( $key, 60 ) ) { + protected function mergeViaLock( $key, Closure $callback, $exptime = 0, $attempts = 10 ) { + if ( !$this->lock( $key, 6 ) ) { return false; } @@ -164,14 +172,17 @@ abstract class BagOStuff { } /** - * @param $key string - * @param $timeout integer [optional] - * @return bool success + * @param string $key + * @param int $timeout [optional] + * @return bool Success */ - public function lock( $key, $timeout = 60 ) { + public function lock( $key, $timeout = 6 ) { + $this->clearLastError(); $timestamp = microtime( true ); // starting UNIX timestamp if ( $this->add( "{$key}:lock", 1, $timeout ) ) { return true; + } elseif ( $this->getLastError() ) { + return false; } $uRTT = ceil( 1e6 * ( microtime( true ) - $timestamp ) ); // estimate RTT (us) @@ -186,15 +197,19 @@ abstract class BagOStuff { $sleep *= 2; } usleep( $sleep ); // back off + $this->clearLastError(); $locked = $this->add( "{$key}:lock", 1, $timeout ); + if ( $this->getLastError() ) { + return false; + } } while ( !$locked ); return $locked; } /** - * @param $key string - * @return bool success + * @param string $key + * @return bool Success */ public function unlock( $key ) { return $this->delete( "{$key}:lock" ); @@ -203,11 +218,11 @@ abstract class BagOStuff { /** * Delete all objects expiring before a certain date. * @param string $date The reference date in MW format - * @param $progressCallback callback|bool Optional, a function which will be called + * @param callable|bool $progressCallback Optional, a function which will be called * regularly during long-running operations with the percentage progress * as the first parameter. * - * @return bool on success, false if unimplemented + * @return bool Success, false if unimplemented */ public function deleteObjectsExpiringBefore( $date, $progressCallback = false ) { // stub @@ -219,7 +234,7 @@ abstract class BagOStuff { /** * Get an associative array containing the item for each of the keys that have items. * @param array $keys List of strings - * @return Array + * @return array */ public function getMulti( array $keys ) { $res = array(); @@ -233,36 +248,40 @@ abstract class BagOStuff { } /** - * @param $key string - * @param $value mixed - * @param $exptime integer - * @return bool success + * Batch insertion + * @param array $data $key => $value assoc array + * @param int $exptime Either an interval in seconds or a unix timestamp for expiry + * @return bool Success + * @since 1.24 */ - public function add( $key, $value, $exptime = 0 ) { - if ( $this->get( $key ) === false ) { - return $this->set( $key, $value, $exptime ); + public function setMulti( array $data, $exptime = 0 ) { + $res = true; + foreach ( $data as $key => $value ) { + if ( !$this->set( $key, $value, $exptime ) ) { + $res = false; + } } - return false; // key already set + return $res; } /** - * @param $key string - * @param $value mixed - * @param $exptime int - * @return bool success + * @param string $key + * @param mixed $value + * @param int $exptime + * @return bool Success */ - public function replace( $key, $value, $exptime = 0 ) { - if ( $this->get( $key ) !== false ) { + public function add( $key, $value, $exptime = 0 ) { + if ( $this->get( $key ) === false ) { return $this->set( $key, $value, $exptime ); } - return false; // key not already set + return false; // key already set } /** * Increase stored value of $key by $value while preserving its TTL * @param string $key Key to increase - * @param $value Integer: Value to add to $key (Default 1) - * @return integer|bool New value or false on failure + * @param int $value Value to add to $key (Default 1) + * @return int|bool New value or false on failure */ public function incr( $key, $value = 1 ) { if ( !$this->lock( $key ) ) { @@ -282,16 +301,59 @@ abstract class BagOStuff { /** * Decrease stored value of $key by $value while preserving its TTL - * @param $key String - * @param $value Integer - * @return integer + * @param string $key + * @param int $value + * @return int */ public function decr( $key, $value = 1 ) { return $this->incr( $key, - $value ); } /** - * @param $text string + * Increase stored value of $key by $value while preserving its TTL + * + * This will create the key with value $init and TTL $ttl if not present + * + * @param string $key + * @param int $ttl + * @param int $value + * @param int $init + * @return bool + * @since 1.24 + */ + public function incrWithInit( $key, $ttl, $value = 1, $init = 1 ) { + return $this->incr( $key, $value ) || + $this->add( $key, (int)$init, $ttl ) || $this->incr( $key, $value ); + } + + /** + * Get the "last error" registered; clearLastError() should be called manually + * @return int ERR_* constant for the "last error" registry + * @since 1.23 + */ + public function getLastError() { + return $this->lastError; + } + + /** + * Clear the "last error" registry + * @since 1.23 + */ + public function clearLastError() { + $this->lastError = self::ERR_NONE; + } + + /** + * Set the "last error" registry + * @param int $err ERR_* constant + * @since 1.23 + */ + protected function setLastError( $err ) { + $this->lastError = $err; + } + + /** + * @param string $text */ public function debug( $text ) { if ( $this->debugMode ) { @@ -302,7 +364,7 @@ abstract class BagOStuff { /** * Convert an optionally relative time to an absolute time - * @param $exptime integer + * @param int $exptime * @return int */ protected function convertExpiry( $exptime ) { @@ -317,8 +379,8 @@ abstract class BagOStuff { * Convert an optionally absolute expiry time to a relative time. If an * absolute time is specified which is in the past, use a short expiry time. * - * @param $exptime integer - * @return integer + * @param int $exptime + * @return int */ protected function convertToRelative( $exptime ) { if ( $exptime >= 86400 * 3650 /* 10 years */ ) { @@ -335,7 +397,7 @@ abstract class BagOStuff { /** * Check if a value is an integer * - * @param $value mixed + * @param mixed $value * @return bool */ protected function isInteger( $value ) { |