87 if ( !empty( $this->params[
'recursive'] ) ) {
91 if ( !isset( $this->params[
'range'] ) ) {
93 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
94 $lbFactory->waitForReplication( [
96 'timeout' => self::LAG_WAIT_TIMEOUT
99 $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
100 $stats->increment(
'refreshlinks.lag_wait_failed' );
105 $extraParams[
'triggeredRecursive'] =
true;
107 $extraParams[
'causeAction'] = $this->params[
'causeAction'];
108 $extraParams[
'causeAgent'] = $this->params[
'causeAgent'];
115 [
'params' => $extraParams ]
119 } elseif ( isset( $this->params[
'pages'] ) ) {
120 foreach ( $this->params[
'pages'] as $nsAndKey ) {
121 list( $ns, $dbKey ) = $nsAndKey;
122 $this->
runForTitle( Title::makeTitleSafe( $ns, $dbKey ) );
137 $services = MediaWikiServices::getInstance();
138 $stats =
$services->getStatsdDataFactory();
139 $lbFactory =
$services->getDBLoadBalancerFactory();
140 $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
142 $page = WikiPage::factory( $title );
143 $page->loadPageData( WikiPage::READ_LATEST );
146 $dbw = $lbFactory->getMainLB()->getConnection(
DB_MASTER );
152 $latest = $title->getLatestRevID( Title::GAID_FOR_UPDATE );
154 if ( !empty( $this->params[
'triggeringRevisionId'] ) ) {
157 $revision = Revision::newFromId(
158 $this->params[
'triggeringRevisionId'],
159 Revision::READ_LATEST
163 $revision = Revision::newFromTitle( $title,
false, Revision::READ_LATEST );
167 $stats->increment(
'refreshlinks.rev_not_found' );
168 $this->
setLastError(
"Revision not found for {$title->getPrefixedDBkey()}" );
170 } elseif ( $revision->getId() != $latest || $revision->getPage() !== $page->getId() ) {
175 $stats->increment(
'refreshlinks.rev_not_current' );
176 $this->
setLastError(
"Revision {$revision->getId()} is not current" );
180 $content = $revision->getContent( Revision::RAW );
183 $content = $revision->getContentHandler()->makeEmptyContent();
186 $parserOutput =
false;
187 $parserOptions = $page->makeParserOptions(
'canonical' );
191 if ( isset( $this->params[
'rootJobTimestamp'] ) ) {
192 $opportunistic = !empty( $this->params[
'isOpportunistic'] );
194 $skewedTimestamp = $this->params[
'rootJobTimestamp'];
195 if ( $opportunistic ) {
201 wfTimestamp( TS_UNIX, $skewedTimestamp ) + self::CLOCK_FUDGE
205 if ( $page->getLinksTimestamp() > $skewedTimestamp ) {
207 $stats->increment(
'refreshlinks.update_skipped' );
211 if ( $page->getTouched() >= $this->params[
'rootJobTimestamp'] || $opportunistic ) {
214 $parserOutput =
$services->getParserCache()->getDirty( $page, $parserOptions );
216 || $parserOutput->getCacheRevisionId() != $revision->getId()
217 || $parserOutput->getCacheTime() < $skewedTimestamp
219 $parserOutput =
false;
225 if ( $parserOutput ) {
226 $stats->increment(
'refreshlinks.parser_cached' );
228 $start = microtime(
true );
230 $parserOutput = $content->getParserOutput(
231 $title, $revision->getId(), $parserOptions,
false );
232 $elapsed = microtime(
true ) - $start;
236 if ( $elapsed >= self::PARSE_THRESHOLD_SEC
237 && $page->shouldCheckParserCache( $parserOptions, $revision->getId() )
238 && $parserOutput->isCacheable()
242 $parserOutput, $page, $parserOptions, $ctime, $revision->getId()
245 $stats->increment(
'refreshlinks.parser_uncached' );
248 $updates = $content->getSecondaryDataUpdates(
251 !empty( $this->params[
'useRecursiveLinksUpdate'] ),
258 $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
260 foreach ( $updates as $update ) {
262 $update->setCause( $this->params[
'causeAction'], $this->params[
'causeAgent'] );
267 $update->setRevision( $revision );
268 if ( !empty( $this->params[
'triggeringUser'] ) ) {
269 $userInfo = $this->params[
'triggeringUser'];
270 if ( $userInfo[
'userId'] ) {
276 $update->setTriggeringUser( $user );
281 foreach ( $updates as $update ) {
282 $update->setTransactionTicket( $ticket );
290 $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );