Convert ParserOutputAccess to PageRecord.
Still needs to downcast to WikiPage in 2 places: 1. To check get a ContentHandler and check if content model is cacheable. We probably should just make all content models cacheable. 2. To call WikiPage::triggerOpportunisticLinksUpdate. I have an elaborate plan for this one, but it will be done separately. Change-Id: Ifd9ab0155dc1fad0c1608dafea05d16292afd057
This commit is contained in:
parent
3a047b749b
commit
cd66d7c335
5 changed files with 66 additions and 28 deletions
|
|
@ -1020,10 +1020,13 @@ return [
|
|||
return new ParserOutputAccess(
|
||||
$services->getParserCache(),
|
||||
$services->getParserCacheFactory()->getRevisionOutputCache( 'rcache' ),
|
||||
$services->getRevisionLookup(),
|
||||
$services->getRevisionRenderer(),
|
||||
$services->getStatsdDataFactory(),
|
||||
$services->getDBLoadBalancerFactory(),
|
||||
LoggerFactory::getProvider()
|
||||
LoggerFactory::getProvider(),
|
||||
$services->getWikiPageFactory(),
|
||||
$services->getTitleFormatter()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use IBufferingStatsdDataFactory;
|
|||
use InvalidArgumentException;
|
||||
use MediaWiki\Logger\Spi as LoggerSpi;
|
||||
use MediaWiki\Parser\RevisionOutputCache;
|
||||
use MediaWiki\Revision\RevisionLookup;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
use MediaWiki\Revision\RevisionRenderer;
|
||||
use ParserCache;
|
||||
|
|
@ -34,8 +35,8 @@ use PoolWorkArticleView;
|
|||
use PoolWorkArticleViewCurrent;
|
||||
use PoolWorkArticleViewOld;
|
||||
use Status;
|
||||
use TitleFormatter;
|
||||
use Wikimedia\Rdbms\ILBFactory;
|
||||
use WikiPage;
|
||||
|
||||
/**
|
||||
* Service for getting rendered output of a given page.
|
||||
|
|
@ -92,6 +93,9 @@ class ParserOutputAccess {
|
|||
*/
|
||||
private $secondaryCache;
|
||||
|
||||
/** @var RevisionLookup */
|
||||
private $revisionLookup;
|
||||
|
||||
/** @var RevisionRenderer */
|
||||
private $revisionRenderer;
|
||||
|
||||
|
|
@ -104,41 +108,56 @@ class ParserOutputAccess {
|
|||
/** @var LoggerSpi */
|
||||
private $loggerSpi;
|
||||
|
||||
/** @var WikiPageFactory */
|
||||
private $wikiPageFactory;
|
||||
|
||||
/** @var TitleFormatter */
|
||||
private $titleFormatter;
|
||||
|
||||
/**
|
||||
* @param ParserCache $primaryCache
|
||||
* @param RevisionOutputCache $secondaryCache
|
||||
* @param RevisionLookup $revisionLookup
|
||||
* @param RevisionRenderer $revisionRenderer
|
||||
* @param IBufferingStatsdDataFactory $statsDataFactory
|
||||
* @param ILBFactory $lbFactory
|
||||
* @param LoggerSpi $loggerSpi
|
||||
* @param WikiPageFactory $wikiPageFactory
|
||||
* @param TitleFormatter $titleFormatter
|
||||
*/
|
||||
public function __construct(
|
||||
ParserCache $primaryCache,
|
||||
RevisionOutputCache $secondaryCache,
|
||||
RevisionLookup $revisionLookup,
|
||||
RevisionRenderer $revisionRenderer,
|
||||
IBufferingStatsdDataFactory $statsDataFactory,
|
||||
ILBFactory $lbFactory,
|
||||
LoggerSpi $loggerSpi
|
||||
LoggerSpi $loggerSpi,
|
||||
WikiPageFactory $wikiPageFactory,
|
||||
TitleFormatter $titleFormatter
|
||||
) {
|
||||
$this->primaryCache = $primaryCache;
|
||||
$this->secondaryCache = $secondaryCache;
|
||||
$this->revisionLookup = $revisionLookup;
|
||||
$this->revisionRenderer = $revisionRenderer;
|
||||
$this->statsDataFactory = $statsDataFactory;
|
||||
$this->lbFactory = $lbFactory;
|
||||
$this->loggerSpi = $loggerSpi;
|
||||
$this->wikiPageFactory = $wikiPageFactory;
|
||||
$this->titleFormatter = $titleFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a cache?
|
||||
*
|
||||
* @param WikiPage $page
|
||||
* @param PageRecord $page
|
||||
* @param ParserOptions $parserOptions ParserOptions to check
|
||||
* @param RevisionRecord|null $rev
|
||||
*
|
||||
* @return string One of the CACHE_XXX constants.
|
||||
*/
|
||||
private function shouldUseCache(
|
||||
WikiPage $page,
|
||||
PageRecord $page,
|
||||
ParserOptions $parserOptions,
|
||||
?RevisionRecord $rev
|
||||
) {
|
||||
|
|
@ -151,11 +170,12 @@ class ParserOutputAccess {
|
|||
// NOTE: when we allow caching of old revisions in the future,
|
||||
// we must not allow caching of deleted revisions.
|
||||
|
||||
if ( !$page->exists() || !$page->getContentHandler()->isParserCacheSupported() ) {
|
||||
$wikiPage = $this->wikiPageFactory->newFromTitle( $page );
|
||||
if ( !$page->exists() || !$wikiPage->getContentHandler()->isParserCacheSupported() ) {
|
||||
return self::CACHE_NONE;
|
||||
}
|
||||
|
||||
if ( !$rev || $rev->getId() === $page->getLatest() ) {
|
||||
if ( !$rev || $rev->getId() === $page->getLatest( PageRecord::LOCAL ) ) {
|
||||
// current revision
|
||||
return self::CACHE_PRIMARY;
|
||||
}
|
||||
|
|
@ -171,7 +191,7 @@ class ParserOutputAccess {
|
|||
/**
|
||||
* Returns the rendered output for the given page if it is present in the cache.
|
||||
*
|
||||
* @param WikiPage $page
|
||||
* @param PageRecord $page
|
||||
* @param ParserOptions $parserOptions
|
||||
* @param RevisionRecord|null $revision
|
||||
* @param int $options Bitfield using the OPT_XXX constants
|
||||
|
|
@ -179,7 +199,7 @@ class ParserOutputAccess {
|
|||
* @return ParserOutput|null
|
||||
*/
|
||||
public function getCachedParserOutput(
|
||||
WikiPage $page,
|
||||
PageRecord $page,
|
||||
ParserOptions $parserOptions,
|
||||
?RevisionRecord $revision = null,
|
||||
int $options = 0
|
||||
|
|
@ -204,7 +224,7 @@ class ParserOutputAccess {
|
|||
* Returns the rendered output for the given page.
|
||||
* Caching and concurrency control is applied.
|
||||
*
|
||||
* @param WikiPage $page
|
||||
* @param PageRecord $page
|
||||
* @param ParserOptions $parserOptions
|
||||
* @param RevisionRecord|null $revision
|
||||
* @param int $options Bitfield using the OPT_XXX constants
|
||||
|
|
@ -223,7 +243,7 @@ class ParserOutputAccess {
|
|||
* - 'nopagetext' (error) The page does not exist
|
||||
*/
|
||||
public function getParserOutput(
|
||||
WikiPage $page,
|
||||
PageRecord $page,
|
||||
ParserOptions $parserOptions,
|
||||
?RevisionRecord $revision = null,
|
||||
int $options = 0
|
||||
|
|
@ -245,7 +265,8 @@ class ParserOutputAccess {
|
|||
}
|
||||
|
||||
if ( !$revision ) {
|
||||
$revision = $page->getRevisionRecord();
|
||||
$revision = $page->getLatest() ?
|
||||
$this->revisionLookup->getRevisionById( $page->getLatest() ) : null;
|
||||
|
||||
if ( !$revision ) {
|
||||
$this->statsDataFactory->increment( "ParserOutputAccess.Status.norev" );
|
||||
|
|
@ -295,14 +316,14 @@ class ParserOutputAccess {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param WikiPage $page
|
||||
* @param PageRecord $page
|
||||
* @param RevisionRecord|null $revision
|
||||
* @param int $options
|
||||
*
|
||||
* @return Status|null
|
||||
*/
|
||||
private function checkPreconditions(
|
||||
WikiPage $page,
|
||||
PageRecord $page,
|
||||
?RevisionRecord $revision = null,
|
||||
int $options = 0
|
||||
): ?Status {
|
||||
|
|
@ -330,7 +351,7 @@ class ParserOutputAccess {
|
|||
'missing-revision-permission',
|
||||
$revision->getId(),
|
||||
$revision->getTimestamp(),
|
||||
$page->getTitle()->getPrefixedDBkey()
|
||||
$this->titleFormatter->getPrefixedDBkey( $page )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -339,15 +360,15 @@ class ParserOutputAccess {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param WikiPage $page
|
||||
* @param PageRecord $page
|
||||
* @param ParserOptions $parserOptions
|
||||
* @param RevisionRecord|null $revision
|
||||
* @param RevisionRecord $revision
|
||||
* @param int $options
|
||||
*
|
||||
* @return PoolWorkArticleView
|
||||
*/
|
||||
private function newPoolWorkArticleView(
|
||||
WikiPage $page,
|
||||
PageRecord $page,
|
||||
ParserOptions $parserOptions,
|
||||
RevisionRecord $revision,
|
||||
int $options
|
||||
|
|
@ -376,7 +397,8 @@ class ParserOutputAccess {
|
|||
$this->revisionRenderer,
|
||||
$this->primaryCache,
|
||||
$this->lbFactory,
|
||||
$this->loggerSpi
|
||||
$this->loggerSpi,
|
||||
$this->wikiPageFactory
|
||||
);
|
||||
|
||||
case $useCache == self::CACHE_SECONDARY:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
*/
|
||||
|
||||
use MediaWiki\Logger\Spi as LoggerSpi;
|
||||
use MediaWiki\Page\PageRecord;
|
||||
use MediaWiki\Page\WikiPageFactory;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
use MediaWiki\Revision\RevisionRenderer;
|
||||
use Wikimedia\Rdbms\ILBFactory;
|
||||
|
|
@ -33,7 +35,7 @@ class PoolWorkArticleViewCurrent extends PoolWorkArticleView {
|
|||
/** @var string */
|
||||
private $workKey;
|
||||
|
||||
/** @var WikiPage */
|
||||
/** @var PageRecord */
|
||||
private $page;
|
||||
|
||||
/** @var ParserCache */
|
||||
|
|
@ -42,29 +44,34 @@ class PoolWorkArticleViewCurrent extends PoolWorkArticleView {
|
|||
/** @var ILBFactory */
|
||||
private $lbFactory;
|
||||
|
||||
/** @var WikiPageFactory */
|
||||
private $wikiPageFactory;
|
||||
|
||||
/**
|
||||
* @param string $workKey
|
||||
* @param WikiPage $page
|
||||
* @param PageRecord $page
|
||||
* @param RevisionRecord $revision Revision to render
|
||||
* @param ParserOptions $parserOptions ParserOptions to use for the parse
|
||||
* @param RevisionRenderer $revisionRenderer
|
||||
* @param ParserCache $parserCache
|
||||
* @param ILBFactory $lbFactory
|
||||
* @param LoggerSpi $loggerSpi
|
||||
* @param WikiPageFactory $wikiPageFactory
|
||||
*/
|
||||
public function __construct(
|
||||
string $workKey,
|
||||
WikiPage $page,
|
||||
PageRecord $page,
|
||||
RevisionRecord $revision,
|
||||
ParserOptions $parserOptions,
|
||||
RevisionRenderer $revisionRenderer,
|
||||
ParserCache $parserCache,
|
||||
ILBFactory $lbFactory,
|
||||
LoggerSpi $loggerSpi
|
||||
LoggerSpi $loggerSpi,
|
||||
WikiPageFactory $wikiPageFactory
|
||||
) {
|
||||
// TODO: Remove support for partially initialized RevisionRecord instances once
|
||||
// Article no longer uses fake revisions.
|
||||
if ( $revision->getPageId() && $revision->getPageId() !== $page->getTitle()->getArticleID() ) {
|
||||
if ( $revision->getPageId() && $revision->getPageId() !== $page->getId() ) {
|
||||
throw new InvalidArgumentException( '$page parameter mismatches $revision parameter' );
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +81,7 @@ class PoolWorkArticleViewCurrent extends PoolWorkArticleView {
|
|||
$this->page = $page;
|
||||
$this->parserCache = $parserCache;
|
||||
$this->lbFactory = $lbFactory;
|
||||
$this->wikiPageFactory = $wikiPageFactory;
|
||||
$this->cacheable = true;
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +103,8 @@ class PoolWorkArticleViewCurrent extends PoolWorkArticleView {
|
|||
* @param ParserOutput $output
|
||||
*/
|
||||
protected function afterWork( ParserOutput $output ) {
|
||||
$this->page->triggerOpportunisticLinksUpdate( $this->parserOutput );
|
||||
$this->wikiPageFactory->newFromTitle( $this->page )
|
||||
->triggerOpportunisticLinksUpdate( $this->parserOutput );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -144,10 +144,13 @@ class ParserOutputAccessTest extends MediaWikiIntegrationTestCase {
|
|||
return new ParserOutputAccess(
|
||||
$parserCache,
|
||||
$revisionOutputCache,
|
||||
$this->getServiceContainer()->getRevisionLookup(),
|
||||
$revRenderer,
|
||||
$stats,
|
||||
$lbFactory,
|
||||
$this->getLoggerSpi()
|
||||
$this->getLoggerSpi(),
|
||||
$this->getServiceContainer()->getWikiPageFactory(),
|
||||
$this->getServiceContainer()->getTitleFormatter()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +254,7 @@ class ParserOutputAccessTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
$revisionStore = $this->createNoOpMock(
|
||||
RevisionStore::class,
|
||||
[ 'getRevisionByTitle', 'getKnownCurrentRevision' ]
|
||||
[ 'getRevisionByTitle', 'getKnownCurrentRevision', 'getRevisionById' ]
|
||||
);
|
||||
$revisionStore->method( 'getRevisionById' )->willReturn( null );
|
||||
$revisionStore->method( 'getRevisionByTitle' )->willReturn( null );
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ class PoolWorkArticleViewCurrentTest extends PoolWorkArticleViewTest {
|
|||
$revisionRenderer,
|
||||
$parserCache,
|
||||
$lbFactory,
|
||||
$this->getLoggerSpi()
|
||||
$this->getLoggerSpi(),
|
||||
$this->getServiceContainer()->getWikiPageFactory()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue