From 280d29215a89ecc68cf860a25f28f7091707a107 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Tue, 29 Sep 2015 17:15:57 -0700 Subject: [PATCH] resourceloader: Vary module_deps on language (in addition to skin) Re-use the md_skin database field for now as to not need a schema change, beause this table is going away soon (T113916). Bug: T113868 Change-Id: I7c7546ec58fd9be0447604989b908dd2084b0fe3 --- includes/resourceloader/ResourceLoader.php | 13 ++-- .../ResourceLoaderFileModule.php | 4 +- .../resourceloader/ResourceLoaderModule.php | 59 ++++++++++--------- maintenance/tables.sql | 2 +- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/includes/resourceloader/ResourceLoader.php b/includes/resourceloader/ResourceLoader.php index dacf013a0e..833fc8848d 100644 --- a/includes/resourceloader/ResourceLoader.php +++ b/includes/resourceloader/ResourceLoader.php @@ -110,28 +110,27 @@ class ResourceLoader implements LoggerAwareInterface { $skin = $context->getSkin(); $lang = $context->getLanguage(); - // Get file dependency information + // Batched version of ResourceLoaderModule::getFileDependencies + $vary = "$skin|$lang"; $res = $dbr->select( 'module_deps', array( 'md_module', 'md_deps' ), array( 'md_module' => $modules, - 'md_skin' => $skin + 'md_skin' => $vary, ), __METHOD__ ); - - // Set modules' dependencies + // Prime in-object cache values for each module $modulesWithDeps = array(); foreach ( $res as $row ) { $module = $this->getModule( $row->md_module ); if ( $module ) { - $module->setFileDependencies( $skin, FormatJson::decode( $row->md_deps, true ) ); + $module->setFileDependencies( $context, FormatJson::decode( $row->md_deps, true ) ); $modulesWithDeps[] = $row->md_module; } } - // Register the absence of a dependency row too foreach ( array_diff( $modules, $modulesWithDeps ) as $name ) { $module = $this->getModule( $name ); if ( $module ) { - $this->getModule( $name )->setFileDependencies( $skin, array() ); + $this->getModule( $name )->setFileDependencies( $context, array() ); } } diff --git a/includes/resourceloader/ResourceLoaderFileModule.php b/includes/resourceloader/ResourceLoaderFileModule.php index ad6903acef..5d762d8d8a 100644 --- a/includes/resourceloader/ResourceLoaderFileModule.php +++ b/includes/resourceloader/ResourceLoaderFileModule.php @@ -416,7 +416,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { $context ); // Collect referenced files - $this->saveFileDependencies( $context->getSkin(), $this->localFileRefs ); + $this->saveFileDependencies( $context, $this->localFileRefs ); return $styles; } @@ -560,7 +560,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { } $files = array_map( array( $this, 'getLocalPath' ), $files ); // File deps need to be treated separately because they're already prefixed - $files = array_merge( $files, $this->getFileDependencies( $context->getSkin() ) ); + $files = array_merge( $files, $this->getFileDependencies( $context ) ); // Filter out any duplicates from getFileDependencies() and others. // Most commonly introduced by compileLessFile(), which always includes the // entry point Less file we already know about. diff --git a/includes/resourceloader/ResourceLoaderModule.php b/includes/resourceloader/ResourceLoaderModule.php index 17e2696201..5b030d7661 100644 --- a/includes/resourceloader/ResourceLoaderModule.php +++ b/includes/resourceloader/ResourceLoaderModule.php @@ -377,34 +377,33 @@ abstract class ResourceLoaderModule { * * These are only image files referenced by the module's stylesheet. * - * @param string $skin Skin name + * @param ResourceLoaderContext $context * @return array List of files */ - protected function getFileDependencies( $skin ) { - // Try in-object cache first - if ( isset( $this->fileDeps[$skin] ) ) { - return $this->fileDeps[$skin]; - } - - $dbr = wfGetDB( DB_SLAVE ); - $deps = $dbr->selectField( 'module_deps', - 'md_deps', - array( - 'md_module' => $this->getName(), - 'md_skin' => $skin, - ), - __METHOD__ - ); + protected function getFileDependencies( ResourceLoaderContext $context ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); - if ( !is_null( $deps ) ) { - $this->fileDeps[$skin] = self::expandRelativePaths( - (array)FormatJson::decode( $deps, true ) + // Try in-object cache first + if ( !isset( $this->fileDeps[$vary] ) ) { + $dbr = wfGetDB( DB_SLAVE ); + $deps = $dbr->selectField( 'module_deps', + 'md_deps', + array( + 'md_module' => $this->getName(), + 'md_skin' => $vary, + ), + __METHOD__ ); - } else { - $this->fileDeps[$skin] = array(); - } - return $this->fileDeps[$skin]; + if ( !is_null( $deps ) ) { + $this->fileDeps[$vary] = self::expandRelativePaths( + (array)FormatJson::decode( $deps, true ) + ); + } else { + $this->fileDeps[$vary] = array(); + } + } + return $this->fileDeps[$vary]; } /** @@ -416,30 +415,32 @@ abstract class ResourceLoaderModule { * @param string $skin Skin name * @param array $deps Array of file names */ - public function setFileDependencies( $skin, $deps ) { - $this->fileDeps[$skin] = $deps; + public function setFileDependencies( ResourceLoaderContext $context, $files ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); + $this->fileDeps[$vary] = $files; } /** * Set the files this module depends on indirectly for a given skin. * * @since 1.26 - * @param string $skin Skin name + * @param ResourceLoaderContext $context * @param array $localFileRefs List of files */ - protected function saveFileDependencies( $skin, $localFileRefs ) { + protected function saveFileDependencies( ResourceLoaderContext $context, $localFileRefs ) { // Normalise array $localFileRefs = array_values( array_unique( $localFileRefs ) ); sort( $localFileRefs ); try { // If the list has been modified since last time we cached it, update the cache - if ( $localFileRefs !== $this->getFileDependencies( $skin ) ) { + if ( $localFileRefs !== $this->getFileDependencies( $context ) ) { + $vary = $context->getSkin() . '|' . $context->getLanguage(); $dbw = wfGetDB( DB_MASTER ); $dbw->replace( 'module_deps', array( array( 'md_module', 'md_skin' ) ), array( 'md_module' => $this->getName(), - 'md_skin' => $skin, + 'md_skin' => $vary, // Use relative paths to avoid ghost entries when $IP changes (T111481) 'md_deps' => FormatJson::encode( self::getRelativePaths( $localFileRefs ) ), ) diff --git a/maintenance/tables.sql b/maintenance/tables.sql index aa0c7ea9a1..4b58b60fbf 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -1524,7 +1524,7 @@ CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_me CREATE TABLE /*_*/module_deps ( -- Module name md_module varbinary(255) NOT NULL, - -- Skin name + -- Module context vary (includes skin and language; called "md_skin" for legacy reasons) md_skin varbinary(32) NOT NULL, -- JSON blob with file dependencies md_deps mediumblob NOT NULL -- 2.20.1