X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FRevision.php;h=c3782ba18a9af2f3a5de40e83b387938d0beec38;hb=36127c29c2d564cc723b6e1cfccca9ba1a0240c8;hp=d9e42ffd8b0efa2b3650ad68b316f148bf322eec;hpb=a7583fb5a9ad9682f91c423c0510b41e2035505b;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Revision.php b/includes/Revision.php index d9e42ffd8b..c3782ba18a 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -19,8 +19,13 @@ * * @file */ + +use Wikimedia\Rdbms\Database; +use Wikimedia\Rdbms\IDatabase; use MediaWiki\Linker\LinkTarget; use MediaWiki\MediaWikiServices; +use Wikimedia\Rdbms\ResultWrapper; +use Wikimedia\Rdbms\FakeResultWrapper; /** * @todo document @@ -216,7 +221,7 @@ class Revision implements IDBAccessObject { // Pre-1.5 ar_text row $attribs['text'] = self::getRevisionText( $row, 'ar_' ); if ( $attribs['text'] === false ) { - throw new MWException( 'Unable to load text from archive row (possibly bug 22624)' ); + throw new MWException( 'Unable to load text from archive row (possibly T24624)' ); } } return new self( $attribs ); @@ -1238,8 +1243,9 @@ class Revision implements IDBAccessObject { /** * Get revision text associated with an old or archive row - * $row is usually an object from wfFetchRow(), both the flags and the text - * field must be included. + * + * Both the flags and the text field must be included. Including the old_id + * field will activate cache usage as long as the $wiki parameter is not set. * * @param stdClass $row The text data * @param string $prefix Table prefix (default 'old_') @@ -1250,8 +1256,6 @@ class Revision implements IDBAccessObject { * @return string|false Text the text requested or false on failure */ public static function getRevisionText( $row, $prefix = 'old_', $wiki = false ) { - - # Get data $textField = $prefix . 'text'; $flagsField = $prefix . 'flags'; @@ -1267,21 +1271,35 @@ class Revision implements IDBAccessObject { return false; } - # Use external methods for external objects, text in table is URL-only then + // Use external methods for external objects, text in table is URL-only then if ( in_array( 'external', $flags ) ) { $url = $text; $parts = explode( '://', $url, 2 ); if ( count( $parts ) == 1 || $parts[1] == '' ) { return false; } - $text = ExternalStore::fetchFromURL( $url, [ 'wiki' => $wiki ] ); - } - // If the text was fetched without an error, convert it - if ( $text !== false ) { - $text = self::decompressRevisionText( $text, $flags ); + if ( isset( $row->old_id ) && $wiki === false ) { + // Make use of the wiki-local revision text cache + $cache = MediaWikiServices::getInstance()->getMainWANObjectCache(); + // The cached value should be decompressed, so handle that and return here + return $cache->getWithSetCallback( + $cache->makeKey( 'revisiontext', 'textid', $row->old_id ), + self::getCacheTTL( $cache ), + function () use ( $url, $wiki, $flags ) { + // No negative caching per Revision::loadText() + $text = ExternalStore::fetchFromURL( $url, [ 'wiki' => $wiki ] ); + + return self::decompressRevisionText( $text, $flags ); + }, + [ 'pcGroup' => self::TEXT_CACHE_GROUP, 'pcTTL' => $cache::TTL_PROC_LONG ] + ); + } else { + $text = ExternalStore::fetchFromURL( $url, [ 'wiki' => $wiki ] ); + } } - return $text; + + return self::decompressRevisionText( $text, $flags ); } /** @@ -1327,6 +1345,13 @@ class Revision implements IDBAccessObject { * @return string|bool Decompressed text, or false on failure */ public static function decompressRevisionText( $text, $flags ) { + global $wgLegacyEncoding, $wgContLang; + + if ( $text === false ) { + // Text failed to be fetched; nothing to do + return false; + } + if ( in_array( 'gzip', $flags ) ) { # Deal with optional compression of archived pages. # This can be done periodically via maintenance/compressOld.php, and @@ -1349,7 +1374,6 @@ class Revision implements IDBAccessObject { $text = $obj->getText(); } - global $wgLegacyEncoding; if ( $text !== false && $wgLegacyEncoding && !in_array( 'utf-8', $flags ) && !in_array( 'utf8', $flags ) ) { @@ -1357,7 +1381,6 @@ class Revision implements IDBAccessObject { # Upconvert on demand. # ("utf8" checked for compatibility with some broken # conversion scripts 2008-12-30) - global $wgContLang; $text = $wgContLang->iconv( $wgLegacyEncoding, 'UTF-8', $text ); } @@ -1473,7 +1496,10 @@ class Revision implements IDBAccessObject { $dbw->insert( 'revision', $row, __METHOD__ ); - $this->mId = $rev_id !== null ? $rev_id : $dbw->insertId(); + if ( $this->mId === null ) { + // Only if nextSequenceValue() was called + $this->mId = $dbw->insertId(); + } // Assertion to try to catch T92046 if ( (int)$this->mId === 0 ) { @@ -1557,15 +1583,14 @@ class Revision implements IDBAccessObject { } /** - * Lazy-load the revision's text. - * Currently hardcoded to the 'text' table storage engine. + * Get the text cache TTL * - * @return string|bool The revision's text, or false on failure + * @param WANObjectCache $cache + * @return integer */ - private function loadText() { + private static function getCacheTTL( WANObjectCache $cache ) { global $wgRevisionCacheExpiry; - $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; @@ -1573,10 +1598,22 @@ class Revision implements IDBAccessObject { $ttl = $wgRevisionCacheExpiry ?: $cache::TTL_UNCACHEABLE; } + return $ttl; + } + + /** + * Lazy-load the revision's text. + * Currently hardcoded to the 'text' table storage engine. + * + * @return string|bool The revision's text, or false on failure + */ + private function loadText() { + $cache = ObjectCache::getMainWANInstance(); + // No negative caching; negative hits on text rows may be due to corrupted replica DBs return $cache->getWithSetCallback( $cache->makeKey( 'revisiontext', 'textid', $this->getTextId() ), - $ttl, + self::getCacheTTL( $cache ), function () { return $this->fetchText(); }, @@ -1781,6 +1818,7 @@ class Revision implements IDBAccessObject { * * @param Title $title * @param int $id + * @param int $flags * @return string|bool False if not found */ static function getTimestampFromId( $title, $id, $flags = 0 ) {