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
__METHOD__ . "($code)-big"
);
foreach ( $res as $row ) {
__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
// 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
$cache[$row->page_title] = '!TOO BIG';
}
// At least include revision ID so page changes are reflected in the hash
$revQuery['joins']
);
foreach ( $res as $row ) {
$revQuery['joins']
);
foreach ( $res as $row ) {
- $name = $this->contLang->lcfirst( $row->page_title );
// Include entries/stubs for all keys in $mostused in adaptive mode
// 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 );
try {
$rev = $revisionStore->newRevisionFromRow( $row );
$content = $rev->getContent( MediaWiki\Revision\SlotRecord::MAIN );
- * @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 ) {
* @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).
// 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 );
);
} else {
// Message page either does not exist or does not override a software message
);
} 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.
// 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.
- public function testNoDBAccess() {
+ public function testNoDBAccessContentLanguage() {
global $wgContLanguageCode;
$dbr = wfGetDB( DB_REPLICA );
global $wgContLanguageCode;
$dbr = wfGetDB( DB_REPLICA );
- $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)" );