jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/403901 )
Change subject: Clear the backlink cache on file delete ...................................................................... Clear the backlink cache on file delete When a file is deleted pages that link to the file (backlinks) are purged. The set of backlinks for a file is cached in the backlink cache, and this is where the set of backlinks that need purging is read from. If, at file delete time, there is a backlink cache for the file but it is not up to date, then backlinks missing from the set of cached backlinks for that file will not be purged, leading to broken links. This patch clears the backlink cache on file delete before initiating purging of backlinks. Bug: T183478 Change-Id: I3bbd79e5a8fa14bf80ceee81e944108edada322e --- M includes/cache/BacklinkCache.php M includes/page/WikiPage.php 2 files changed, 47 insertions(+), 13 deletions(-) Approvals: Aaron Schulz: Looks good to me, approved jenkins-bot: Verified diff --git a/includes/cache/BacklinkCache.php b/includes/cache/BacklinkCache.php index 4341daa..48809d0 100644 --- a/includes/cache/BacklinkCache.php +++ b/includes/cache/BacklinkCache.php @@ -28,6 +28,7 @@ use Wikimedia\Rdbms\ResultWrapper; use Wikimedia\Rdbms\FakeResultWrapper; use Wikimedia\Rdbms\IDatabase; +use MediaWiki\MediaWikiServices; /** * Class for fetching backlink lists, approximate backlink counts and @@ -71,6 +72,11 @@ protected $fullResultCache = []; /** + * @var WANObjectCache + */ + protected $wanCache; + + /** * Local copy of a database object. * * Accessor: BacklinkCache::getDB() @@ -93,6 +99,7 @@ */ public function __construct( Title $title ) { $this->title = $title; + $this->wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache(); } /** @@ -122,11 +129,12 @@ } /** - * Clear locally stored data and database object. + * Clear locally stored data and database object. Invalidate data in memcache. */ public function clear() { $this->partitionCache = []; $this->fullResultCache = []; + $this->wanCache->touchCheckKey( $this->makeCheckKey() ); unset( $this->db ); } @@ -324,7 +332,6 @@ public function getNumLinks( $table, $max = INF ) { global $wgUpdateRowsPerJob; - $cache = ObjectCache::getMainWANInstance(); // 1) try partition cache ... if ( isset( $this->partitionCache[$table] ) ) { $entry = reset( $this->partitionCache[$table] ); @@ -337,15 +344,22 @@ return min( $max, $this->fullResultCache[$table]->numRows() ); } - $memcKey = $cache->makeKey( + $memcKey = $this->wanCache->makeKey( 'numbacklinks', md5( $this->title->getPrefixedDBkey() ), $table ); // 3) ... fallback to memcached ... - $count = $cache->get( $memcKey ); - if ( $count ) { + $curTTL = INF; + $count = $this->wanCache->get( + $memcKey, + $curTTL, + [ + $this->makeCheckKey() + ] + ); + if ( $count && ( $curTTL > 0 ) ) { return min( $max, $count ); } @@ -359,7 +373,7 @@ // Fetch the full title info, since the caller will likely need it next $count = $this->getLinks( $table, false, false, $max )->count(); if ( $count < $max ) { // full count - $cache->set( $memcKey, $count, self::CACHE_EXPIRY ); + $this->wanCache->set( $memcKey, $count, self::CACHE_EXPIRY ); } } @@ -383,7 +397,6 @@ return $this->partitionCache[$table][$batchSize]['batches']; } - $cache = ObjectCache::getMainWANInstance(); $this->partitionCache[$table][$batchSize] = false; $cacheEntry =& $this->partitionCache[$table][$batchSize]; @@ -395,7 +408,7 @@ return $cacheEntry['batches']; } - $memcKey = $cache->makeKey( + $memcKey = $this->wanCache->makeKey( 'backlinks', md5( $this->title->getPrefixedDBkey() ), $table, @@ -403,8 +416,15 @@ ); // 3) ... fallback to memcached ... - $memcValue = $cache->get( $memcKey ); - if ( is_array( $memcValue ) ) { + $curTTL = 0; + $memcValue = $this->wanCache->get( + $memcKey, + $curTTL, + [ + $this->makeCheckKey() + ] + ); + if ( is_array( $memcValue ) && ( $curTTL > 0 ) ) { $cacheEntry = $memcValue; wfDebug( __METHOD__ . ": got from memcached $memcKey\n" ); @@ -435,15 +455,15 @@ } // Save partitions to memcached - $cache->set( $memcKey, $cacheEntry, self::CACHE_EXPIRY ); + $this->wanCache->set( $memcKey, $cacheEntry, self::CACHE_EXPIRY ); // Save backlink count to memcached - $memcKey = $cache->makeKey( + $memcKey = $this->wanCache->makeKey( 'numbacklinks', md5( $this->title->getPrefixedDBkey() ), $table ); - $cache->set( $memcKey, $cacheEntry['numRows'], self::CACHE_EXPIRY ); + $this->wanCache->set( $memcKey, $cacheEntry['numRows'], self::CACHE_EXPIRY ); wfDebug( __METHOD__ . ": got from database\n" ); @@ -543,4 +563,16 @@ return TitleArray::newFromResult( new FakeResultWrapper( array_values( $mergedRes ) ) ); } + + /** + * Returns check key for the backlinks cache for a particular title + * + * @return String + */ + private function makeCheckKey() { + return $this->wanCache->makeKey( + 'backlinks', + md5( $this->title->getPrefixedDBkey() ) + ); + } } diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index 5029d1d..6847671 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -3353,6 +3353,8 @@ */ public static function onArticleDelete( Title $title ) { // Update existence markers on article/talk tabs... + // Clear Backlink cache first so that purge jobs use more up-to-date backlink information + BacklinkCache::get( $title )->clear(); $other = $title->getOtherPage(); $other->purgeSquid(); -- To view, visit https://gerrit.wikimedia.org/r/403901 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3bbd79e5a8fa14bf80ceee81e944108edada322e Gerrit-PatchSet: 5 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Cparle <cpa...@wikimedia.org> Gerrit-Reviewer: Aaron Schulz <asch...@wikimedia.org> Gerrit-Reviewer: Cparle <cpa...@wikimedia.org> Gerrit-Reviewer: Gergő Tisza <gti...@wikimedia.org> Gerrit-Reviewer: Krinkle <krinklem...@gmail.com> Gerrit-Reviewer: MarkTraceur <mholmqu...@wikimedia.org> Gerrit-Reviewer: Matthias Mullie <mmul...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits