MediaWiki  master
PoolWorkArticleViewCurrent.php
Go to the documentation of this file.
1 <?php
21 use MediaWiki\Logger\Spi as LoggerSpi;
27 
35  private $workKey;
37  private $page;
39  private $parserCache;
41  private $lbFactory;
43  private $wikiPageFactory;
44 
57  public function __construct(
58  string $workKey,
59  PageRecord $page,
62  RevisionRenderer $revisionRenderer,
63  ParserCache $parserCache,
64  ILBFactory $lbFactory,
65  LoggerSpi $loggerSpi,
66  WikiPageFactory $wikiPageFactory,
67  bool $cacheable = true
68  ) {
69  // TODO: Remove support for partially initialized RevisionRecord instances once
70  // Article no longer uses fake revisions.
71  if ( $revision->getPageId() && $revision->getPageId() !== $page->getId() ) {
72  throw new InvalidArgumentException( '$page parameter mismatches $revision parameter' );
73  }
74 
75  parent::__construct( $workKey, $revision, $parserOptions, $revisionRenderer, $loggerSpi );
76 
77  $this->workKey = $workKey;
78  $this->page = $page;
79  $this->parserCache = $parserCache;
80  $this->lbFactory = $lbFactory;
81  $this->wikiPageFactory = $wikiPageFactory;
82  $this->cacheable = $cacheable;
83  }
84 
88  public function doWork() {
89  // Reduce effects of race conditions for slow parses (T48014)
90  $cacheTime = wfTimestampNow();
91 
92  $status = $this->renderRevision();
94  $output = $status->getValue();
95 
96  if ( $output ) {
97  if ( $this->cacheable && $output->isCacheable() ) {
98  $this->parserCache->save(
99  $output,
100  $this->page,
101  $this->parserOptions,
102  $cacheTime,
103  $this->revision->getId()
104  );
105  }
106 
107  $this->wikiPageFactory->newFromTitle( $this->page )
108  ->triggerOpportunisticLinksUpdate( $output );
109  }
110 
111  return $status;
112  }
113 
117  public function getCachedWork() {
118  $parserOutput = $this->parserCache->get( $this->page, $this->parserOptions );
119 
120  $logger = $this->loggerSpi->getLogger( 'PoolWorkArticleView' );
121  $logger->debug( $parserOutput ? 'parser cache hit' : 'parser cache miss' );
122 
123  return $parserOutput ? Status::newGood( $parserOutput ) : false;
124  }
125 
130  public function fallback( $fast ) {
131  $parserOutput = $this->parserCache->getDirty( $this->page, $this->parserOptions );
132 
133  $logger = $this->loggerSpi->getLogger( 'dirty' );
134 
135  if ( !$parserOutput ) {
136  $logger->info( 'dirty missing' );
137  return false;
138  }
139 
140  if ( $fast ) {
141  /* Check if the stale response is from before the last write to the
142  * DB by this user. Declining to return a stale response in this
143  * case ensures that the user will see their own edit after page
144  * save.
145  *
146  * Note that the CP touch time is the timestamp of the shutdown of
147  * the save request, so there is a bias towards avoiding fast stale
148  * responses of potentially several seconds.
149  */
150  $lastWriteTime = $this->lbFactory->getChronologyProtectorTouched();
151  $cacheTime = MWTimestamp::convert( TS_UNIX, $parserOutput->getCacheTime() );
152  if ( $lastWriteTime && $cacheTime <= $lastWriteTime ) {
153  $logger->info(
154  'declining to send dirty output since cache time ' .
155  '{cacheTime} is before last write time {lastWriteTime}',
156  [
157  'workKey' => $this->workKey,
158  'cacheTime' => $cacheTime,
159  'lastWriteTime' => $lastWriteTime,
160  ]
161  );
162  // Forget this ParserOutput -- we will request it again if
163  // necessary in slow mode. There might be a newer entry
164  // available by that time.
165  return false;
166  }
167  }
168 
169  $logger->info( $fast ? 'fast dirty output' : 'dirty output', [ 'workKey' => $this->workKey ] );
170 
171  $status = Status::newGood( $parserOutput );
172  $status->warning( 'view-pool-dirty-output' );
173  $status->warning( $fast ? 'view-pool-contention' : 'view-pool-overload' );
174  return $status;
175  }
176 
177 }
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.
Cache for ParserOutput objects corresponding to the latest page revisions.
Definition: ParserCache.php:64
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, LoggerSpi $loggerSpi, WikiPageFactory $wikiPageFactory, bool $cacheable=true)
PoolCounter protected work wrapping RenderedRevision->getRevisionParserOutput.
ParserOptions $parserOptions
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:85
Service provider interface for \Psr\Log\LoggerInterface implementation libraries.
Definition: Spi.php:38
Data record representing a page that is (or used to be, or could be) an editable page on a wiki.
Definition: PageRecord.php:24
getId( $wikiId=self::LOCAL)
Returns the page ID.
Manager of ILoadBalancer objects and, indirectly, IDatabase connections.
Definition: ILBFactory.php:46