From: Roan Kattouw Date: Fri, 19 Jul 2019 23:51:01 +0000 (-0700) Subject: MessageCache: Fix isMainCacheable() logic for non-content languages X-Git-Tag: 1.34.0-rc.0~933^2 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dcompta/comptes/journal.php?a=commitdiff_plain;ds=sidebyside;h=bcb6b9d0eb0656690af2dbdca0ae67d4bf73147b;p=lhc%2Fweb%2Fwiklou.git MessageCache: Fix isMainCacheable() logic for non-content languages The way isMainCacheable() was used, it always returned false in non-content languages, because it would try to find strings like 'hidetoc/fr' in the array of message keys (which contains strings like 'hidetoc'). The consequence of this was that MessageCache would check the database for a MediaWiki:hidetoc/fr page even if it already knew that that page didn't exist. This is a substantial performance hit when requesting lots of messages, like when building version hashes for ResourceLoader's startup module. Follows-up 4fc5ba8bf83102b02. Bug: T228555 Change-Id: I20433175ca919acc1c995f4a9cd50ca53afcdd02 --- diff --git a/includes/cache/MessageCache.php b/includes/cache/MessageCache.php index b0716b18b3..a8bcfc6b44 100644 --- a/includes/cache/MessageCache.php +++ b/includes/cache/MessageCache.php @@ -525,9 +525,8 @@ class MessageCache { __METHOD__ . "($code)-big" ); foreach ( $res as $row ) { - $name = $this->contLang->lcfirst( $row->page_title ); // Include entries/stubs for all keys in $mostused in adaptive mode - if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) { + if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $row->page_title, $overridable ) ) { $cache[$row->page_title] = '!TOO BIG'; } // At least include revision ID so page changes are reflected in the hash @@ -549,9 +548,8 @@ class MessageCache { $revQuery['joins'] ); foreach ( $res as $row ) { - $name = $this->contLang->lcfirst( $row->page_title ); // Include entries/stubs for all keys in $mostused in adaptive mode - if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) { + if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $row->page_title, $overridable ) ) { try { $rev = $revisionStore->newRevisionFromRow( $row ); $content = $rev->getContent( MediaWiki\Revision\SlotRecord::MAIN ); @@ -592,14 +590,17 @@ class MessageCache { } /** - * @param string $name Message name with lowercase first letter + * @param string $name Message name (possibly with /code suffix) * @param array $overridable Map of (key => unused) for software-defined messages * @return bool */ private function isMainCacheable( $name, array $overridable ) { + // Convert first letter to lowercase, and strip /code suffix + $name = $this->contLang->lcfirst( $name ); + $msg = preg_replace( '/\/[a-z0-9-]{2,}$/', '', $name ); // Include common conversion table pages. This also avoids problems with // Installer::parse() bailing out due to disallowed DB queries (T207979). - return ( isset( $overridable[$name] ) || strpos( $name, 'conversiontable/' ) === 0 ); + return ( isset( $overridable[$msg] ) || strpos( $name, 'conversiontable/' ) === 0 ); } /** @@ -1069,8 +1070,7 @@ class MessageCache { ); } else { // Message page either does not exist or does not override a software message - $name = $this->contLang->lcfirst( $title ); - if ( !$this->isMainCacheable( $name, $this->overridable ) ) { + if ( !$this->isMainCacheable( $title, $this->overridable ) ) { // Message page does not override any software-defined message. A custom // message might be defined to have content or settings specific to the wiki. // Load the message page, utilizing the individual message cache as needed. diff --git a/tests/phpunit/includes/cache/MessageCacheTest.php b/tests/phpunit/includes/cache/MessageCacheTest.php index 2fa662b88b..35dacac598 100644 --- a/tests/phpunit/includes/cache/MessageCacheTest.php +++ b/tests/phpunit/includes/cache/MessageCacheTest.php @@ -204,7 +204,7 @@ class MessageCacheTest extends MediaWikiLangTestCase { ]; } - public function testNoDBAccess() { + public function testNoDBAccessContentLanguage() { global $wgContLanguageCode; $dbr = wfGetDB( DB_REPLICA ); @@ -218,7 +218,22 @@ class MessageCacheTest extends MediaWikiLangTestCase { $dbr->restoreFlags(); - $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries" ); + $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries (content language)" ); + } + + public function testNoDBAccessNonContentLanguage() { + $dbr = wfGetDB( DB_REPLICA ); + + MessageCache::singleton()->getMsgFromNamespace( 'allpages/nl', 'nl' ); + + $this->assertEquals( 0, $dbr->trxLevel() ); + $dbr->setFlag( DBO_TRX, $dbr::REMEMBER_PRIOR ); // make queries trigger TRX + + MessageCache::singleton()->getMsgFromNamespace( 'go/nl', 'nl' ); + + $dbr->restoreFlags(); + + $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries (non-content language)" ); } /**