Switch the sidebar cache to using checkKeys
authorAaron Schulz <aschulz@wikimedia.org>
Mon, 19 Feb 2018 11:50:29 +0000 (03:50 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Mon, 19 Feb 2018 12:10:39 +0000 (04:10 -0800)
The avoids the long delete() loop in MessageCache::replace()
and has better separation of concern.

Change-Id: I0acb0119058fa92fcafb52a5850f5dad4aaa94d2

includes/cache/MessageCache.php
includes/skins/Skin.php

index d5ff6cb..bbbb074 100644 (file)
@@ -300,7 +300,7 @@ class MessageCache {
                }
 
                if ( !$success ) {
-                       $cacheKey = $this->clusterCache->makeKey( 'messages', $code ); # Key in memc for messages
+                       $cacheKey = $this->clusterCache->makeKey( 'messages', $code );
                        # Try the global cache. If it is empty, try to acquire a lock. If
                        # the lock can't be acquired, wait for the other thread to finish
                        # and then try the global cache a second time.
@@ -622,19 +622,7 @@ class MessageCache {
 
                                // Relay the purge. Touching this check key expires cache contents
                                // and local cache (APC) validation hash across all datacenters.
-                               $this->wanCache->touchCheckKey( $this->wanCache->makeKey( 'messages', $code ) );
-                               // Also delete cached sidebar... just in case it is affected
-                               // @TODO: shouldn't this be $code === $wgLanguageCode?
-                               if ( $code === 'en' ) {
-                                       // Purge all language sidebars, e.g. on ?action=purge to the sidebar messages
-                                       $codes = array_keys( Language::fetchLanguageNames() );
-                               } else {
-                                       // Purge only the sidebar for this language
-                                       $codes = [ $code ];
-                               }
-                               foreach ( $codes as $code ) {
-                                       $this->wanCache->delete( $this->wanCache->makeKey( 'sidebar', $code ) );
-                               }
+                               $this->wanCache->touchCheckKey( $this->getCheckKey( $code ) );
 
                                // Purge the message in the message blob store
                                $resourceloader = RequestContext::getMain()->getOutput()->getResourceLoader();
@@ -701,7 +689,7 @@ class MessageCache {
                $value = $this->wanCache->get(
                        $this->wanCache->makeKey( 'messages', $code, 'hash', 'v1' ),
                        $curTTL,
-                       [ $this->wanCache->makeKey( 'messages', $code ) ]
+                       [ $this->getCheckKey( $code ) ]
                );
 
                if ( $value ) {
@@ -1199,13 +1187,14 @@ class MessageCache {
        }
 
        /**
-        * Clear all stored messages. Mainly used after a mass rebuild.
+        * Clear all stored messages in global and local cache
+        *
+        * Mainly used after a mass rebuild
         */
        function clear() {
                $langs = Language::fetchLanguageNames( null, 'mw' );
                foreach ( array_keys( $langs ) as $code ) {
-                       # Global and local caches
-                       $this->wanCache->touchCheckKey( $this->wanCache->makeKey( 'messages', $code ) );
+                       $this->wanCache->touchCheckKey( $this->getCheckKey( $code ) );
                }
 
                $this->mLoadedLanguages = [];
@@ -1283,6 +1272,14 @@ class MessageCache {
                }
        }
 
+       /**
+        * @param string $code Language code
+        * @return string WAN cache key usable as a "check key" against language page edits
+        */
+       public function getCheckKey( $code ) {
+               return $this->wanCache->makeKey( 'messages', $code );
+       }
+
        /**
         * @param Content|null $content Content or null if the message page does not exist
         * @return string|bool|null Returns false if $content is null and null on error
index 4f271c7..65a300a 100644 (file)
@@ -1253,7 +1253,7 @@ abstract class Skin extends ContextSource {
         *
         * @return array
         */
-       function buildSidebar() {
+       public function buildSidebar() {
                global $wgEnableSidebarCache, $wgSidebarCacheExpiry;
 
                $callback = function ( $old = null, &$ttl = null ) {
@@ -1267,13 +1267,22 @@ abstract class Skin extends ContextSource {
                        return $bar;
                };
 
-               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+               $msgCache = MessageCache::singleton();
+               $wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+
                $sidebar = $wgEnableSidebarCache
-                       ? $cache->getWithSetCallback(
-                               $cache->makeKey( 'sidebar', $this->getLanguage()->getCode() ),
+                       ? $wanCache->getWithSetCallback(
+                               $wanCache->makeKey( 'sidebar', $this->getLanguage()->getCode() ),
                                $wgSidebarCacheExpiry,
                                $callback,
-                               [ 'lockTSE' => 30 ]
+                               [
+                                       'checkKeys' => [
+                                               // Unless there is both no exact $code override nor an i18n definition
+                                               // in the the software, the only MediaWiki page to check is for $code.
+                                               $msgCache->getCheckKey( $this->getLanguage()->getCode() )
+                                       ],
+                                       'lockTSE' => 30
+                               ]
                        )
                        : $callback();