diff options
author | Amir Sarabadani <ladsgroup@gmail.com> | 2021-12-06 22:22:00 +0100 |
---|---|---|
committer | Ladsgroup <Ladsgroup@gmail.com> | 2021-12-16 14:38:47 +0000 |
commit | f010b324c6773e8d7dd82e782d766a4e93f6f859 (patch) | |
tree | ac400915104d680cbe71573977274fa90961cc76 | |
parent | 50a8a49735cbfac2ac41b8741a4867cca8d50fd4 (diff) |
Revision: Add two caching layers to loadSlotRecords for template pages
This is currently making a lot of (serial) DB queries during every page
parse. At least one for every transcluded page.
Using Memcached should significantly reduce DB load, and apcu should
notably reduce latency when parsing large articles.
This is currently limited to NS_TEMPLATE to avoid overwhelming caches
with a long tail of unlikely re-used metadata about non-transcluded
pages (every parsed article) and rare non-template transclusions.
Bug: T297147
Change-Id: I630603eaffcae3700b2843fb97c5bedf8d29da9e
-rw-r--r-- | includes/Revision/RevisionStore.php | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/includes/Revision/RevisionStore.php b/includes/Revision/RevisionStore.php index 8491dfa83464..d3860a32e740 100644 --- a/includes/Revision/RevisionStore.php +++ b/includes/Revision/RevisionStore.php @@ -41,6 +41,7 @@ use MediaWiki\DAO\WikiAwareEntity; use MediaWiki\HookContainer\HookContainer; use MediaWiki\HookContainer\HookRunner; use MediaWiki\Linker\LinkTarget; +use MediaWiki\MediaWikiServices; use MediaWiki\Page\LegacyArticleIdAccess; use MediaWiki\Page\PageIdentity; use MediaWiki\Page\PageIdentityValue; @@ -1366,6 +1367,50 @@ class RevisionStore * @return SlotRecord[] */ private function loadSlotRecords( $revId, $queryFlags, PageIdentity $page ) { + // TODO: Find a way to add NS_MODULE from Scribunto here + if ( $page->getNamespace() !== NS_TEMPLATE ) { + $res = $this->loadSlotRecordsFromDb( $revId, $queryFlags, $page ); + return $this->constructSlotRecords( $revId, $res, $queryFlags, $page ); + } + + // TODO: These caches should not be needed. See T297147#7563670 + $localCache = MediaWikiServices::getInstance()->getLocalServerObjectCache(); + $res = $localCache->getWithSetCallback( + $localCache->makeKey( + 'revision-slots', + $page->getWikiId(), + $page->getId( $page->getWikiId() ), + $revId + ), + $localCache::TTL_HOUR, + function () use ( $revId, $queryFlags, $page ) { + return $this->cache->getWithSetCallback( + $this->cache->makeKey( + 'revision-slots', + $page->getWikiId(), + $page->getId( $page->getWikiId() ), + $revId + ), + WANObjectCache::TTL_DAY, + function () use ( $revId, $queryFlags, $page ) { + $res = $this->loadSlotRecordsFromDb( $revId, $queryFlags, $page ); + if ( !$res ) { + // Avoid caching + return false; + } + return $res; + } + ); + } + ); + if ( !$res ) { + $res = []; + } + + return $this->constructSlotRecords( $revId, $res, $queryFlags, $page ); + } + + private function loadSlotRecordsFromDb( $revId, $queryFlags, PageIdentity $page ): array { $revQuery = $this->getSlotsQueryInfo( [ 'content' ] ); list( $dbMode, $dbOptions ) = DBAccessObjectUtils::getDBOptions( $queryFlags ); @@ -1397,8 +1442,7 @@ class RevisionStore $page ); } - - return $this->constructSlotRecords( $revId, $res, $queryFlags, $page ); + return iterator_to_array( $res ); } /** @@ -1503,9 +1547,6 @@ class RevisionStore $this->constructSlotRecords( $revId, $slotRows, $queryFlags, $page ) ); } else { - // XXX: do we need the same kind of caching here - // that getKnownCurrentRevision uses (if $revId == page_latest?) - $slots = new RevisionSlots( function () use( $revId, $queryFlags, $page ) { return $this->loadSlotRecords( $revId, $queryFlags, $page ); } ); |