Merge "API: Use message-per-value for apihelp-query+allcategories-param-prop"
[lhc/web/wiklou.git] / includes / libs / objectcache / BagOStuff.php
index 5507e9d..cc07db4 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Classes to cache objects in PHP accelerators, SQL database or DBA files
- *
  * Copyright © 2003-2004 Brion Vibber <brion@pobox.com>
  * https://www.mediawiki.org/
  *
@@ -61,6 +59,9 @@ abstract class BagOStuff implements LoggerAwareInterface {
        const ERR_UNREACHABLE = 2; // can't connect
        const ERR_UNEXPECTED = 3; // response gave some error
 
+       /** Bitfield constants for get()/getMulti() */
+       const READ_LATEST = 1; // use latest data for replicated stores
+
        public function __construct( array $params = array() ) {
                if ( isset( $params['logger'] ) ) {
                        $this->setLogger( $params['logger'] );
@@ -88,9 +89,10 @@ abstract class BagOStuff implements LoggerAwareInterface {
         * Get an item with the given key. Returns false if it does not exist.
         * @param string $key
         * @param mixed $casToken [optional]
+        * @param integer $flags Bitfield; supports READ_LATEST [optional]
         * @return mixed Returns false on failure
         */
-       abstract public function get( $key, &$casToken = null );
+       abstract public function get( $key, &$casToken = null, $flags = 0 );
 
        /**
         * Set an item.
@@ -140,11 +142,17 @@ abstract class BagOStuff implements LoggerAwareInterface {
         */
        protected function mergeViaCas( $key, $callback, $exptime = 0, $attempts = 10 ) {
                do {
+                       $this->clearLastError();
                        $casToken = null; // passed by reference
                        $currentValue = $this->get( $key, $casToken );
+                       if ( $this->getLastError() ) {
+                               return false; // don't spam retries (retry only on races)
+                       }
+
                        // Derive the new value from the old value
                        $value = call_user_func( $callback, $this, $key, $currentValue );
 
+                       $this->clearLastError();
                        if ( $value === false ) {
                                $success = true; // do nothing
                        } elseif ( $currentValue === false ) {
@@ -154,6 +162,9 @@ abstract class BagOStuff implements LoggerAwareInterface {
                                // Try to update the key, failing if it gets changed in the meantime
                                $success = $this->cas( $casToken, $key, $value, $exptime );
                        }
+                       if ( $this->getLastError() ) {
+                               return false; // IO error; don't spam retries
+                       }
                } while ( !$success && --$attempts );
 
                return $success;
@@ -187,14 +198,17 @@ abstract class BagOStuff implements LoggerAwareInterface {
                        return false;
                }
 
+               $this->clearLastError();
                $currentValue = $this->get( $key );
-               // Derive the new value from the old value
-               $value = call_user_func( $callback, $this, $key, $currentValue );
+               if ( !$this->getLastError() ) {
+                       // Derive the new value from the old value
+                       $value = call_user_func( $callback, $this, $key, $currentValue );
 
-               if ( $value === false ) {
-                       $success = true; // do nothing
-               } else {
-                       $success = $this->set( $key, $value, $exptime ); // set the new value
+                       if ( $value === false ) {
+                               $success = true; // do nothing
+                       } else {
+                               $success = $this->set( $key, $value, $exptime ); // set the new value
+                       }
                }
 
                if ( !$this->unlock( $key ) ) {
@@ -264,14 +278,13 @@ abstract class BagOStuff implements LoggerAwareInterface {
                return false;
        }
 
-       /* *** Emulated functions *** */
-
        /**
         * Get an associative array containing the item for each of the keys that have items.
         * @param array $keys List of strings
+        * @param integer $flags Bitfield; supports READ_LATEST [optional]
         * @return array
         */
-       public function getMulti( array $keys ) {
+       public function getMulti( array $keys, $flags = 0 ) {
                $res = array();
                foreach ( $keys as $key ) {
                        $val = $this->get( $key );