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

Reply via email to