jenkins-bot has submitted this change and it was merged.

Change subject: More multi-DC tweaks to MessageCache::load()
......................................................................


More multi-DC tweaks to MessageCache::load()

* Use hash key volatility to propagate invalidations over DCs
  in addition to memcached->APC instances.
* Make use of stale APC cache due to hash mismatch instead
  of waiting around in some cases. This is similar to the
  TTL expiry and volatility cases.
* Renamed $hashExpired and added some comments for clarity.

Change-Id: I8890fb174cae72c4ce8872df64f52f5cbd55183b
---
M includes/cache/MessageCache.php
1 file changed, 31 insertions(+), 24 deletions(-)

Approvals:
  Ori.livneh: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/includes/cache/MessageCache.php b/includes/cache/MessageCache.php
index 8fe0bf9..304c4f2 100644
--- a/includes/cache/MessageCache.php
+++ b/includes/cache/MessageCache.php
@@ -260,29 +260,30 @@
                # Loading code starts
                $success = false; # Keep track of success
                $staleCache = false; # a cache array with expired data, or 
false if none has been loaded
-               $hashExpired = false; # whether the cluster-local validation 
hash is stale
                $where = array(); # Debug info, delayed to avoid spamming debug 
log too much
 
-               # Local cache
-               # Hash of the contents is stored in memcache, to detect if 
local cache goes
-               # out of date (e.g. due to replace() on some other server)
-               if ( $wgUseLocalMessageCache ) {
-                       list( $hash, $hashExpired ) = $this->getValidationHash( 
$code );
-                       if ( $hash ) {
-                               $cache = $this->getLocalCache( $code );
-                               if ( !$cache || !isset( $cache['HASH'] ) || 
$cache['HASH'] !== $hash ) {
-                                       $where[] = 'local cache is empty or has 
the wrong hash';
-                               } elseif ( $this->isCacheExpired( $cache ) ) {
-                                       $where[] = 'local cache is expired';
-                                       $staleCache = $cache;
-                               } elseif ( $hashExpired ) {
-                                       $where[] = 'local cache validation key 
is expired';
-                                       $staleCache = $cache;
-                               } else {
-                                       $where[] = 'got from local cache';
-                                       $success = true;
-                                       $this->mCache[$code] = $cache;
-                               }
+               # Hash of the contents is stored in memcache, to detect if 
data-center cache
+               # or local cache goes out of date (e.g. due to replace() on 
some other server)
+               list( $hash, $hashVolatile ) = $this->getValidationHash( $code 
);
+
+               if ( $wgUseLocalMessageCache && $hash ) {
+                       # Try the local cache and check against the cluster 
hash key...
+                       $cache = $this->getLocalCache( $code );
+                       if ( !$cache ) {
+                               $where[] = 'local cache is empty';
+                       } elseif ( !isset( $cache['HASH'] ) || $cache['HASH'] 
!== $hash ) {
+                               $where[] = 'local cache has the wrong hash';
+                               $staleCache = $cache;
+                       } elseif ( $this->isCacheExpired( $cache ) ) {
+                               $where[] = 'local cache is expired';
+                               $staleCache = $cache;
+                       } elseif ( $hashVolatile ) {
+                               $where[] = 'local cache validation key is 
expired/volatile';
+                               $staleCache = $cache;
+                       } else {
+                               $where[] = 'got from local cache';
+                               $success = true;
+                               $this->mCache[$code] = $cache;
                        }
                }
 
@@ -292,7 +293,7 @@
                        # the lock can't be acquired, wait for the other thread 
to finish
                        # and then try the global cache a second time.
                        for ( $failedAttempts = 0; $failedAttempts < 2; 
$failedAttempts++ ) {
-                               if ( $hashExpired && $staleCache ) {
+                               if ( $hashVolatile && $staleCache ) {
                                        # Do not bother fetching the whole 
cache blob to avoid I/O.
                                        # Instead, just try to get the 
non-blocking $statusKey lock
                                        # below, and use the local stale value 
if it was not acquired.
@@ -303,6 +304,12 @@
                                                $where[] = 'global cache is 
empty';
                                        } elseif ( $this->isCacheExpired( 
$cache ) ) {
                                                $where[] = 'global cache is 
expired';
+                                               $staleCache = $cache;
+                                       } elseif ( $hashVolatile ) {
+                                               # DB results are slave lag 
prone until the holdoff TTL passes.
+                                               # By then, updates should be 
reflected in loadFromDBWithLock().
+                                               # One thread renerates the 
cache while others use old values.
+                                               $where[] = 'global cache is 
expired/volatile';
                                                $staleCache = $cache;
                                        } else {
                                                $where[] = 'got from global 
cache';
@@ -319,8 +326,8 @@
 
                                # We need to call loadFromDB. Limit the 
concurrency to one process.
                                # This prevents the site from going down when 
the cache expires.
+                               # Note that the slam-protection lock here is 
non-blocking.
                                if ( $this->loadFromDBWithLock( $code, $where ) 
) {
-                                       # Load from DB complete, no need to 
retry
                                        $success = true;
                                        break;
                                } elseif ( $staleCache ) {
@@ -644,7 +651,7 @@
         * Get the md5 used to validate the local disk cache
         *
         * @param string $code
-        * @return array (hash or false, bool expiry status)
+        * @return array (hash or false, bool expiry/volatility status)
         */
        protected function getValidationHash( $code ) {
                $curTTL = null;

-- 
To view, visit https://gerrit.wikimedia.org/r/230967
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I8890fb174cae72c4ce8872df64f52f5cbd55183b
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Ori.livneh <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to