MediaWiki 1.44.0
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 PoolCounter $poolCounter,
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(
94 $poolCounter,
97 $revisionRenderer,
99 );
100
101 $this->workKey = $poolCounter->getKey();
102 $this->page = $page;
103 $this->parserCache = $parserCache;
104 $this->lbFactory = $lbFactory;
105 $this->chronologyProtector = $chronologyProtector;
106 $this->wikiPageFactory = $wikiPageFactory;
107 $this->cacheable = $cacheable;
108 $this->triggerLinksUpdate = $triggerLinksUpdate;
109 }
110
114 public function doWork() {
115 // T371713: Temporary statistics collection code to determine
116 // feasibility of Parsoid selective update
117 $sampleRate = MediaWikiServices::getInstance()->getMainConfig()->get(
119 );
120 $doSample = ( $sampleRate && mt_rand( 1, $sampleRate ) === 1 );
121
122 $previousOutput = null;
123 if ( $this->parserOptions->getUseParsoid() || $doSample ) {
124 // Parsoid can do selective updates, so it is worth checking the
125 // cache for an existing entry. Not worth it for the legacy
126 // parser, though.
127 $previousOutput = $this->parserCache->getDirty( $this->page, $this->parserOptions ) ?: null;
128 }
129 $status = $this->renderRevision( $previousOutput, $doSample, 'PoolWorkArticleViewCurrent' );
131 $output = $status->getValue();
132
133 if ( $output ) {
134 if ( $this->cacheable && $output->isCacheable() ) {
135 $this->parserCache->save(
136 $output,
137 $this->page,
138 $this->parserOptions
139 );
140 }
141
142 if ( $this->triggerLinksUpdate ) {
143 $this->wikiPageFactory->newFromTitle( $this->page )->triggerOpportunisticLinksUpdate( $output );
144 }
145 }
146
147 return $status;
148 }
149
153 public function getCachedWork() {
154 $parserOutput = $this->parserCache->get( $this->page, $this->parserOptions );
155
156 $logger = $this->loggerSpi->getLogger( 'PoolWorkArticleView' );
157 $logger->debug( $parserOutput ? 'parser cache hit' : 'parser cache miss' );
158
159 return $parserOutput ? Status::newGood( $parserOutput ) : false;
160 }
161
166 public function fallback( $fast ) {
167 $parserOutput = $this->parserCache->getDirty( $this->page, $this->parserOptions );
168
169 $logger = $this->loggerSpi->getLogger( 'dirty' );
170
171 if ( !$parserOutput ) {
172 $logger->info( 'dirty missing' );
173 return false;
174 }
175
176 if ( $fast ) {
177 /* Check if the stale response is from before the last write to the
178 * DB by this user. Declining to return a stale response in this
179 * case ensures that the user will see their own edit after page
180 * save.
181 *
182 * Note that the CP touch time is the timestamp of the shutdown of
183 * the save request, so there is a bias towards avoiding fast stale
184 * responses of potentially several seconds.
185 */
186 $lastWriteTime = $this->chronologyProtector->getTouched( $this->lbFactory->getMainLB() );
187 $cacheTime = MWTimestamp::convert( TS_UNIX, $parserOutput->getCacheTime() );
188 if ( $lastWriteTime && $cacheTime <= $lastWriteTime ) {
189 $logger->info(
190 'declining to send dirty output since cache time ' .
191 '{cacheTime} is before last write time {lastWriteTime}',
192 [
193 'workKey' => $this->workKey,
194 'cacheTime' => $cacheTime,
195 'lastWriteTime' => $lastWriteTime,
196 ]
197 );
198 // Forget this ParserOutput -- we will request it again if
199 // necessary in slow mode. There might be a newer entry
200 // available by that time.
201 return false;
202 }
203 }
204
205 $logger->info( $fast ? 'fast dirty output' : 'dirty output', [ 'workKey' => $this->workKey ] );
206
207 $status = Status::newGood( $parserOutput );
208 $status->warning( 'view-pool-dirty-output' );
209 $status->warning( $fast ? 'view-pool-contention' : 'view-pool-overload' );
210 return $status;
211 }
212
213}
214
216class_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.
Semaphore semantics to restrict how many workers may concurrently perform a task.
PoolWorkArticleView for the current revision of a page, using ParserCache.
__construct(PoolCounter $poolCounter, 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.