MediaWiki 1.41.2
PoolWorkArticleViewCurrent.php
Go to the documentation of this file.
1<?php
21use MediaWiki\Logger\Spi as LoggerSpi;
30
38 private $workKey;
40 private $page;
42 private $parserCache;
44 private $lbFactory;
46 private $wikiPageFactory;
48 private bool $triggerLinksUpdate;
49 private ChronologyProtector $chronologyProtector;
50
65 public function __construct(
66 string $workKey,
67 PageRecord $page,
68 RevisionRecord $revision,
69 ParserOptions $parserOptions,
70 RevisionRenderer $revisionRenderer,
71 ParserCache $parserCache,
72 ILBFactory $lbFactory,
73 ChronologyProtector $chronologyProtector,
74 LoggerSpi $loggerSpi,
75 WikiPageFactory $wikiPageFactory,
76 bool $cacheable = true,
77 bool $triggerLinksUpdate = false
78 ) {
79 // TODO: Remove support for partially initialized RevisionRecord instances once
80 // Article no longer uses fake revisions.
81 if ( $revision->getPageId() && $revision->getPageId() !== $page->getId() ) {
82 throw new InvalidArgumentException( '$page parameter mismatches $revision parameter' );
83 }
84
85 parent::__construct( $workKey, $revision, $parserOptions, $revisionRenderer, $loggerSpi );
86
87 $this->workKey = $workKey;
88 $this->page = $page;
89 $this->parserCache = $parserCache;
90 $this->lbFactory = $lbFactory;
91 $this->chronologyProtector = $chronologyProtector;
92 $this->wikiPageFactory = $wikiPageFactory;
93 $this->cacheable = $cacheable;
94 $this->triggerLinksUpdate = $triggerLinksUpdate;
95 }
96
100 public function doWork() {
101 // Reduce effects of race conditions for slow parses (T48014)
102 $cacheTime = wfTimestampNow();
103
104 $status = $this->renderRevision();
106 $output = $status->getValue();
107
108 if ( $output ) {
109 if ( $this->cacheable && $output->isCacheable() ) {
110 $this->parserCache->save(
111 $output,
112 $this->page,
113 $this->parserOptions,
114 $cacheTime,
115 $this->revision->getId()
116 );
117 }
118
119 if ( $this->triggerLinksUpdate ) {
120 $this->wikiPageFactory->newFromTitle( $this->page )
121 ->triggerOpportunisticLinksUpdate( $output );
122 }
123 }
124
125 return $status;
126 }
127
131 public function getCachedWork() {
132 $parserOutput = $this->parserCache->get( $this->page, $this->parserOptions );
133
134 $logger = $this->loggerSpi->getLogger( 'PoolWorkArticleView' );
135 $logger->debug( $parserOutput ? 'parser cache hit' : 'parser cache miss' );
136
137 return $parserOutput ? Status::newGood( $parserOutput ) : false;
138 }
139
144 public function fallback( $fast ) {
145 $parserOutput = $this->parserCache->getDirty( $this->page, $this->parserOptions );
146
147 $logger = $this->loggerSpi->getLogger( 'dirty' );
148
149 if ( !$parserOutput ) {
150 $logger->info( 'dirty missing' );
151 return false;
152 }
153
154 if ( $fast ) {
155 /* Check if the stale response is from before the last write to the
156 * DB by this user. Declining to return a stale response in this
157 * case ensures that the user will see their own edit after page
158 * save.
159 *
160 * Note that the CP touch time is the timestamp of the shutdown of
161 * the save request, so there is a bias towards avoiding fast stale
162 * responses of potentially several seconds.
163 */
164 $lastWriteTime = $this->chronologyProtector->getTouched( $this->lbFactory->getMainLB() );
165 $cacheTime = MWTimestamp::convert( TS_UNIX, $parserOutput->getCacheTime() );
166 if ( $lastWriteTime && $cacheTime <= $lastWriteTime ) {
167 $logger->info(
168 'declining to send dirty output since cache time ' .
169 '{cacheTime} is before last write time {lastWriteTime}',
170 [
171 'workKey' => $this->workKey,
172 'cacheTime' => $cacheTime,
173 'lastWriteTime' => $lastWriteTime,
174 ]
175 );
176 // Forget this ParserOutput -- we will request it again if
177 // necessary in slow mode. There might be a newer entry
178 // available by that time.
179 return false;
180 }
181 }
182
183 $logger->info( $fast ? 'fast dirty output' : 'dirty output', [ 'workKey' => $this->workKey ] );
184
185 $status = Status::newGood( $parserOutput );
186 $status->warning( 'view-pool-dirty-output' );
187 $status->warning( $fast ? 'view-pool-contention' : 'view-pool-overload' );
188 return $status;
189 }
190
191}
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Service for creating WikiPage objects.
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:58
Library for creating and parsing MW-style timestamps.
Cache for ParserOutput objects corresponding to the latest page revisions.
Set options of the Parser.
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.
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.