From 68c0eefc850956e0e80a11e5f73f011832ae1375 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Tue, 14 Feb 2017 12:55:11 -0800 Subject: [PATCH] resourceloader: Limit module_deps write lock to unique index Follows-up 1d15085bb3. The column has a unique index for module name and skin/language pair. Previously the write lock was on module name, which meant that shortly after deployment, the following happens: * Files change on disk. * (1-5min pass) * First startup module request after 5min http-cache expires. Detects one or more changes and updates the version hash of that module. * Web client subsequently requests this module (if used on that page). The first time that request comes in, it's a varnish cache miss and will make RL load all files from disk related to that module and update the cache index in the module_deps table. At this point most popular skin/lang pairs fail, except one. As a result, the other rows remain stale. * (7-30 days varnish expiry pass OR another change to the module deploys) * Web client requests this module and tries to update its skin/lang pair for that module. One simple change in January 2016 changes jquery.tablesorter to load a PNG file instead of a GIF file. Now, over a year later, there are still a dozen skin/lang pairs in enwiki.module_deps with stale data, which is causing various suble bugs, as well as filesystem calls for files that don't exist. Ref T113916 (refactor module_deps). Ref T158105 (stale cache bug). Bug: T158105 Change-Id: Ib6c024bfa8d35ce2d622ba4242291daedb507d5e --- includes/resourceloader/ResourceLoaderModule.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/resourceloader/ResourceLoaderModule.php b/includes/resourceloader/ResourceLoaderModule.php index fd74a82818..71e5939c2f 100644 --- a/includes/resourceloader/ResourceLoaderModule.php +++ b/includes/resourceloader/ResourceLoaderModule.php @@ -468,14 +468,14 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface { try { // If the list has been modified since last time we cached it, update the cache if ( $localFileRefs !== $this->getFileDependencies( $context ) ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); $cache = ObjectCache::getLocalClusterInstance(); - $key = $cache->makeKey( __METHOD__, $this->getName() ); + $key = $cache->makeKey( __METHOD__, $this->getName(), $vary ); $scopeLock = $cache->getScopedLock( $key, 0 ); if ( !$scopeLock ) { return; // T124649; avoid write slams } - $vary = $context->getSkin() . '|' . $context->getLanguage(); // Use relative paths to avoid ghost entries when $IP changes (T111481) $deps = FormatJson::encode( self::getRelativePaths( $localFileRefs ) ); $dbw = wfGetDB( DB_MASTER ); -- 2.20.1