MediaWiki master
PoolWorkArticleViewCurrent.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\PoolCounter;
22
23use InvalidArgumentException;
24use MediaWiki\Logger\Spi as LoggerSpi;
38
46 private $workKey;
48 private $page;
50 private $parserCache;
52 private $lbFactory;
54 private $wikiPageFactory;
56 private bool $triggerLinksUpdate;
57 private ChronologyProtector $chronologyProtector;
58
73 public function __construct(
74 string $workKey,
75 PageRecord $page,
78 RevisionRenderer $revisionRenderer,
79 ParserCache $parserCache,
80 ILBFactory $lbFactory,
81 ChronologyProtector $chronologyProtector,
82 LoggerSpi $loggerSpi,
83 WikiPageFactory $wikiPageFactory,
84 bool $cacheable = true,
85 bool $triggerLinksUpdate = false
86 ) {
87 // TODO: Remove support for partially initialized RevisionRecord instances once
88 // Article no longer uses fake revisions.
89 if ( $revision->getPageId() && $revision->getPageId() !== $page->getId() ) {
90 throw new InvalidArgumentException( '$page parameter mismatches $revision parameter' );
91 }
92
93 parent::__construct( $workKey, $revision, $parserOptions, $revisionRenderer, $loggerSpi );
94
95 $this->workKey = $workKey;
96 $this->page = $page;
97 $this->parserCache = $parserCache;
98 $this->lbFactory = $lbFactory;
99 $this->chronologyProtector = $chronologyProtector;
100 $this->wikiPageFactory = $wikiPageFactory;
101 $this->cacheable = $cacheable;
102 $this->triggerLinksUpdate = $triggerLinksUpdate;
103 }
104
108 public function doWork() {
109 // T371713: Temporary statistics collection code to determine
110 // feasibility of Parsoid selective update
111 $sampleRate = MediaWikiServices::getInstance()->getMainConfig()->get(
113 );
114 $doSample = ( $sampleRate && mt_rand( 1, $sampleRate ) === 1 );
115
116 $previousOutput = null;
117 if ( $this->parserOptions->getUseParsoid() || $doSample ) {
118 // Parsoid can do selective updates, so it is worth checking the
119 // cache for an existing entry. Not worth it for the legacy
120 // parser, though.
121 $previousOutput = $this->parserCache->getDirty( $this->page, $this->parserOptions ) ?: null;
122 }
123 $status = $this->renderRevision( $previousOutput, $doSample, 'PoolWorkArticleViewCurrent' );
125 $output = $status->getValue();
126
127 if ( $output ) {
128 if ( $this->cacheable && $output->isCacheable() ) {
129 $this->parserCache->save(
130 $output,
131 $this->page,
132 $this->parserOptions
133 );
134 }
135
136 if ( $this->triggerLinksUpdate ) {
137 $this->wikiPageFactory->newFromTitle( $this->page )->triggerOpportunisticLinksUpdate( $output );
138 }
139 }
140
141 return $status;
142 }
143
147 public function getCachedWork() {
148 $parserOutput = $this->parserCache->get( $this->page, $this->parserOptions );
149
150 $logger = $this->loggerSpi->getLogger( 'PoolWorkArticleView' );
151 $logger->debug( $parserOutput ? 'parser cache hit' : 'parser cache miss' );
152
153 return $parserOutput ? Status::newGood( $parserOutput ) : false;
154 }
155
160 public function fallback( $fast ) {
161 $parserOutput = $this->parserCache->getDirty( $this->page, $this->parserOptions );
162
163 $logger = $this->loggerSpi->getLogger( 'dirty' );
164
165 if ( !$parserOutput ) {
166 $logger->info( 'dirty missing' );
167 return false;
168 }
169
170 if ( $fast ) {
171 /* Check if the stale response is from before the last write to the
172 * DB by this user. Declining to return a stale response in this
173 * case ensures that the user will see their own edit after page
174 * save.
175 *
176 * Note that the CP touch time is the timestamp of the shutdown of
177 * the save request, so there is a bias towards avoiding fast stale
178 * responses of potentially several seconds.
179 */
180 $lastWriteTime = $this->chronologyProtector->getTouched( $this->lbFactory->getMainLB() );
181 $cacheTime = MWTimestamp::convert( TS_UNIX, $parserOutput->getCacheTime() );
182 if ( $lastWriteTime && $cacheTime <= $lastWriteTime ) {
183 $logger->info(
184 'declining to send dirty output since cache time ' .
185 '{cacheTime} is before last write time {lastWriteTime}',
186 [
187 'workKey' => $this->workKey,
188 'cacheTime' => $cacheTime,
189 'lastWriteTime' => $lastWriteTime,
190 ]
191 );
192 // Forget this ParserOutput -- we will request it again if
193 // necessary in slow mode. There might be a newer entry
194 // available by that time.
195 return false;
196 }
197 }
198
199 $logger->info( $fast ? 'fast dirty output' : 'dirty output', [ 'workKey' => $this->workKey ] );
200
201 $status = Status::newGood( $parserOutput );
202 $status->warning( 'view-pool-dirty-output' );
203 $status->warning( $fast ? 'view-pool-contention' : 'view-pool-overload' );
204 return $status;
205 }
206
207}
208
210class_alias( PoolWorkArticleViewCurrent::class, 'PoolWorkArticleViewCurrent' );
A class containing constants representing the names of configuration variables.
const ParsoidSelectiveUpdateSampleRate
Name constant for the ParsoidSelectiveUpdateSampleRate setting, for use with Config::get()
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Service for creating WikiPage objects.
Cache for ParserOutput objects corresponding to the latest page revisions.
Set options of the Parser.
ParserOutput is a rendering of a Content object or a message.
PoolWorkArticleView for the current revision of a page, using ParserCache.
__construct(string $workKey, PageRecord $page, RevisionRecord $revision, ParserOptions $parserOptions, RevisionRenderer $revisionRenderer, ParserCache $parserCache, ILBFactory $lbFactory, ChronologyProtector $chronologyProtector, LoggerSpi $loggerSpi, WikiPageFactory $wikiPageFactory, bool $cacheable=true, bool $triggerLinksUpdate=false)
PoolCounter protected work wrapping RenderedRevision->getRevisionParserOutput.
renderRevision(?ParserOutput $previousOutput=null, bool $doSample=false, string $sourceLabel='')
Render the given revision.
Page revision base class.
getPageId( $wikiId=self::LOCAL)
Get the page ID.
The RevisionRenderer service provides access to rendered output for revisions.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
Library for creating and parsing MW-style timestamps.
Provide a given client with protection against visible database lag.
Service provider interface to create \Psr\Log\LoggerInterface objects.
Definition Spi.php:64
Data record representing a page that is (or used to be, or could be) an editable page on a wiki.
getId( $wikiId=self::LOCAL)
Returns the page ID.
Manager of ILoadBalancer objects and, indirectly, IDatabase connections.