X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fobjectcache%2FBagOStuff.php;h=56f1be23b5252792cbd636a9f82defb45db06287;hb=13e33c28983461d5b8bdc1dece0cd0a35347a261;hp=217142c0b4e43c71c73da239ce2d96001944cc8a;hpb=214a19f5ed0de0496ff82013e28ef9004c07f723;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/objectcache/BagOStuff.php b/includes/objectcache/BagOStuff.php index 217142c0b4..56f1be23b5 100644 --- a/includes/objectcache/BagOStuff.php +++ b/includes/objectcache/BagOStuff.php @@ -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,13 +143,13 @@ 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 ) { + 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 = 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,10 +248,27 @@ abstract class BagOStuff { } /** - * @param $key string - * @param $value mixed - * @param $exptime integer + * 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 setMulti( array $data, $exptime = 0 ) { + $res = true; + foreach ( $data as $key => $value ) { + if ( !$this->set( $key, $value, $exptime ) ) { + $res = false; + } + } + return $res; + } + + /** + * @param string $key + * @param mixed $value + * @param int $exptime + * @return bool Success */ public function add( $key, $value, $exptime = 0 ) { if ( $this->get( $key ) === false ) { @@ -246,11 +278,11 @@ abstract class BagOStuff { } /** - * @param $key string - * @param $value mixed - * @param $exptime int - * @return bool success - * @deprecated 1.23 + * @param string $key + * @param mixed $value + * @param int $exptime + * @return bool Success + * @deprecated since 1.23 */ public function replace( $key, $value, $exptime = 0 ) { wfDeprecated( __METHOD__, '1.23' ); @@ -263,8 +295,8 @@ abstract class BagOStuff { /** * 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 ) ) { @@ -284,16 +316,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 integer $ttl + * @param integer $value + * @param integer $init + * @return bool + * @since 1.24 + */ + public function incrWithInit( $key, $ttl, $value = 1, $init = 1 ) { + return $this->incr( $key, $value ) || + $this->add( $key, $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 ) { @@ -304,7 +379,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 ) { @@ -319,8 +394,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 */ ) { @@ -337,7 +412,7 @@ abstract class BagOStuff { /** * Check if a value is an integer * - * @param $value mixed + * @param mixed $value * @return bool */ protected function isInteger( $value ) {