Merge "Make $wgRevisionCacheExpiry default to one week"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 9 Sep 2016 10:37:49 +0000 (10:37 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 9 Sep 2016 10:37:49 +0000 (10:37 +0000)
1  2 
includes/DefaultSettings.php
includes/Revision.php

@@@ -2123,7 -2123,7 +2123,7 @@@ $wgDefaultExternalStore = false
   *
   * Set to 0 to disable, or number of seconds before cache expiry.
   */
- $wgRevisionCacheExpiry = 0;
+ $wgRevisionCacheExpiry = 86400 * 7;
  
  /** @} */ # end text storage }
  
@@@ -5581,11 -5581,6 +5581,11 @@@ $wgRateLimits = 
                'ip' => [ 8, 60 ],
                'newbie' => [ 8, 60 ],
        ],
 +      // Changing the content model of a page
 +      'editcontentmodel' => [
 +              'newbie' => [ 2, 120 ],
 +              'user' => [ 8, 60 ],
 +      ],
  ];
  
  /**
diff --combined includes/Revision.php
@@@ -1577,19 -1577,20 +1577,20 @@@ class Revision implements IDBAccessObje
         * @return string|bool The revision's text, or false on failure
         */
        private function loadText() {
-               // Caching may be beneficial for massive use of external storage
                global $wgRevisionCacheExpiry;
  
-               if ( !$wgRevisionCacheExpiry ) {
-                       return $this->fetchText();
-               }
                $cache = ObjectCache::getMainWANInstance();
+               if ( $cache->getQoS( $cache::ATTR_EMULATION ) <= $cache::QOS_EMULATION_SQL ) {
+                       // Do not cache RDBMs blobs in...the RDBMs store
+                       $ttl = $cache::TTL_UNCACHEABLE;
+               } else {
+                       $ttl = $wgRevisionCacheExpiry ?: $cache::TTL_UNCACHEABLE;
+               }
  
                // No negative caching; negative hits on text rows may be due to corrupted replica DBs
                return $cache->getWithSetCallback(
-                       $key = $cache->makeKey( 'revisiontext', 'textid', $this->getTextId() ),
-                       $wgRevisionCacheExpiry,
+                       $cache->makeKey( 'revisiontext', 'textid', $this->getTextId() ),
+                       $ttl,
                        function () {
                                return $this->fetchText();
                        },
                        $row = null;
                }
  
 +              // Callers doing updates will pass in READ_LATEST as usual. Since the text/blob tables
 +              // do not normally get rows changed around, set READ_LATEST_IMMUTABLE in those cases.
 +              $flags = $this->mQueryFlags;
 +              $flags |= DBAccessObjectUtils::hasFlags( $flags, self::READ_LATEST )
 +                      ? self::READ_LATEST_IMMUTABLE
 +                      : 0;
 +
 +              list( $index, $options, $fallbackIndex, $fallbackOptions ) =
 +                      DBAccessObjectUtils::getDBOptions( $flags );
 +
                if ( !$row ) {
                        // Text data is immutable; check replica DBs first.
 -                      $dbr = wfGetDB( DB_REPLICA );
 -                      $row = $dbr->selectRow( 'text',
 +                      $row = wfGetDB( $index )->selectRow(
 +                              'text',
                                [ 'old_text', 'old_flags' ],
                                [ 'old_id' => $textId ],
 -                              __METHOD__ );
 +                              __METHOD__,
 +                              $options
 +                      );
                }
  
 -              // Fallback to the master in case of replica DB lag. Also use FOR UPDATE if it was
 -              // used to fetch this revision to avoid missing the row due to REPEATABLE-READ.
 -              $forUpdate = ( $this->mQueryFlags & self::READ_LOCKING == self::READ_LOCKING );
 -              if ( !$row && ( $forUpdate || wfGetLB()->getServerCount() > 1 ) ) {
 -                      $dbw = wfGetDB( DB_MASTER );
 -                      $row = $dbw->selectRow( 'text',
 +              // Fallback to DB_MASTER in some cases if the row was not found
 +              if ( !$row && $fallbackIndex !== null ) {
 +                      // Use FOR UPDATE if it was used to fetch this revision. This avoids missing the row
 +                      // due to REPEATABLE-READ. Also fallback to the master if READ_LATEST is provided.
 +                      $row = wfGetDB( $fallbackIndex )->selectRow(
 +                              'text',
                                [ 'old_text', 'old_flags' ],
                                [ 'old_id' => $textId ],
                                __METHOD__,
 -                              $forUpdate ? [ 'FOR UPDATE' ] : [] );
 +                              $fallbackOptions
 +                      );
                }
  
                if ( !$row ) {