summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmir Sarabadani <ladsgroup@gmail.com>2021-12-06 22:22:00 +0100
committerLadsgroup <Ladsgroup@gmail.com>2021-12-16 14:38:47 +0000
commitf010b324c6773e8d7dd82e782d766a4e93f6f859 (patch)
treeac400915104d680cbe71573977274fa90961cc76
parent50a8a49735cbfac2ac41b8741a4867cca8d50fd4 (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.php51
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 );
} );