Merge "Made InfoAction::invalidateCache() use READ_LATEST"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 1 Apr 2015 00:19:04 +0000 (00:19 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 1 Apr 2015 00:19:04 +0000 (00:19 +0000)
includes/Revision.php
includes/db/Database.php
includes/db/LoadBalancer.php
includes/diff/DifferenceEngine.php

index 356cd32..a13499a 100644 (file)
@@ -297,7 +297,10 @@ class Revision implements IDBAccessObject {
        }
 
        /**
-        * Given a set of conditions, fetch a revision.
+        * Given a set of conditions, fetch a revision
+        *
+        * This method is used then a revision ID is qualified and
+        * will incorporate some basic slave/master fallback logic
         *
         * @param array $conditions
         * @param int $flags (optional)
@@ -305,10 +308,24 @@ class Revision implements IDBAccessObject {
         */
        private static function newFromConds( $conditions, $flags = 0 ) {
                $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+
                $rev = self::loadFromConds( $db, $conditions, $flags );
+               // Make sure new pending/committed revision are visibile later on
+               // within web requests to certain avoid bugs like T93866 and T94407.
+               if ( !$rev
+                       && !( $flags & self::READ_LATEST )
+                       && wfGetLB()->getServerCount() > 1
+                       && wfGetLB()->hasOrMadeRecentMasterChanges()
+               ) {
+                       $flags = self::READ_LATEST;
+                       $db = wfGetDB( DB_MASTER );
+                       $rev = self::loadFromConds( $db, $conditions, $flags );
+               }
+
                if ( $rev ) {
                        $rev->mQueryFlags = $flags;
                }
+
                return $rev;
        }
 
@@ -1481,9 +1498,9 @@ class Revision implements IDBAccessObject {
         * @return string|bool The revision's text, or false on failure
         */
        protected function loadText() {
-
                // Caching may be beneficial for massive use of external storage
                global $wgRevisionCacheExpiry, $wgMemc;
+
                $textId = $this->getTextId();
                $key = wfMemcKey( 'revisiontext', 'textid', $textId );
                if ( $wgRevisionCacheExpiry ) {
index b3c81f9..cbd8be5 100644 (file)
@@ -3611,6 +3611,7 @@ abstract class DatabaseBase implements IDatabase {
                        $this->runOnTransactionPreCommitCallbacks();
                        $this->doCommit( $fname );
                        if ( $this->mTrxDoneWrites ) {
+                               $this->mDoneWrites = microtime( true );
                                $this->getTransactionProfiler()->transactionWritingOut(
                                        $this->mServer, $this->mDBname, $this->mTrxShortId );
                        }
@@ -3691,6 +3692,7 @@ abstract class DatabaseBase implements IDatabase {
                $this->runOnTransactionPreCommitCallbacks();
                $this->doCommit( $fname );
                if ( $this->mTrxDoneWrites ) {
+                       $this->mDoneWrites = microtime( true );
                        $this->getTransactionProfiler()->transactionWritingOut(
                                $this->mServer, $this->mDBname, $this->mTrxShortId );
                }
index 4e0a5b9..48c636e 100644 (file)
@@ -1022,8 +1022,7 @@ class LoadBalancer {
        }
 
        /**
-        * Determine if there are any pending changes that need to be rolled back
-        * or committed.
+        * Determine if there are pending changes in a transaction by this thread
         * @since 1.23
         * @return bool
         */
@@ -1044,6 +1043,42 @@ class LoadBalancer {
                return false;
        }
 
+       /**
+        * Get the timestamp of the latest write query done by this thread
+        * @since 1.25
+        * @return float|bool UNIX timestamp or false
+        */
+       public function lastMasterChangeTimestamp() {
+               $lastTime = false;
+               // Always 0, but who knows.. :)
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               $lastTime = max( $lastTime, $conn->lastDoneWrites() );
+                       }
+               }
+               return $lastTime;
+       }
+
+       /**
+        * Check if this load balancer object had any recent or still
+        * pending writes issued against it by this PHP thread
+        *
+        * @param float $age How many seconds ago is "recent" [defaults to mWaitTimeout]
+        * @return bool
+        * @since 1.25
+        */
+       public function hasOrMadeRecentMasterChanges( $age = null ) {
+               $age = ( $age === null ) ? $this->mWaitTimeout : $age;
+
+               return ( $this->hasMasterChanges()
+                       || $this->lastMasterChangeTimestamp() > microtime( true ) - $age );
+       }
+
        /**
         * @param mixed $value
         * @return mixed
index de8dd43..77bbd36 100644 (file)
@@ -1233,12 +1233,6 @@ class DifferenceEngine extends ContextSource {
                // Load the new revision object
                if ( $this->mNewid ) {
                        $this->mNewRev = Revision::newFromId( $this->mNewid );
-
-                       if ( !$this->mNewRev && wfGetLB()->getServerCount() > 1 ) {
-                               // Try harder… This is being hit after a rollback where we show the
-                               // diff immediately after the edit happened. T93866
-                               $this->mNewRev = Revision::newFromId( $this->mNewid, Revision::READ_LATEST );
-                       }
                } else {
                        $this->mNewRev = Revision::newFromTitle(
                                $this->getTitle(),