X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fjobqueue%2Fjobs%2FRefreshLinksJob.php;h=0b6d30776bf73d73460f44a2d436132c95489087;hp=8854c6560fa520ebbc2240e10bd2f19d6f799cda;hb=4df0c71911500466a6330b8fe29c623ef5b51e41;hpb=8f829de5f04070e3254113590a5b192156dc85da diff --git a/includes/jobqueue/jobs/RefreshLinksJob.php b/includes/jobqueue/jobs/RefreshLinksJob.php index 8854c6560f..0b6d30776b 100644 --- a/includes/jobqueue/jobs/RefreshLinksJob.php +++ b/includes/jobqueue/jobs/RefreshLinksJob.php @@ -21,7 +21,6 @@ * @ingroup JobQueue */ use MediaWiki\MediaWikiServices; -use Wikimedia\Rdbms\DBReplicationWaitError; /** * Job to update link tables for pages @@ -89,13 +88,11 @@ class RefreshLinksJob extends Job { // From then on, we know that any template changes at the time the base job was // enqueued will be reflected in backlink page parses when the leaf jobs run. if ( !isset( $this->params['range'] ) ) { - try { - $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); - $lbFactory->waitForReplication( [ + $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); + if ( !$lbFactory->waitForReplication( [ 'wiki' => wfWikiID(), 'timeout' => self::LAG_WAIT_TIMEOUT - ] ); - } catch ( DBReplicationWaitError $e ) { // only try so hard + ] ) ) { // only try so hard $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); $stats->increment( 'refreshlinks.lag_wait_failed' ); } @@ -146,6 +143,11 @@ class RefreshLinksJob extends Job { $dbw = $lbFactory->getMainLB()->getConnection( DB_MASTER ); /** @noinspection PhpUnusedLocalVariableInspection */ $scopedLock = LinksUpdate::acquirePageLock( $dbw, $page->getId(), 'job' ); + if ( $scopedLock === null ) { + // Another job is already updating the page, likely for an older revision (T170596). + $this->setLastError( 'LinksUpdate already running for this page, try again later.' ); + return false; + } // Get the latest ID *after* acquirePageLock() flushed the transaction. // This is used to detect edits/moves after loadPageData() but before the scope lock. // The works around the chicken/egg problem of determining the scope lock key. @@ -245,43 +247,24 @@ class RefreshLinksJob extends Job { $stats->increment( 'refreshlinks.parser_uncached' ); } - $updates = $content->getSecondaryDataUpdates( - $title, - null, - !empty( $this->params['useRecursiveLinksUpdate'] ), - $parserOutput - ); - - // For legacy hook handlers doing updates via LinksUpdateConstructed, make sure - // any pending writes they made get flushed before the doUpdate() calls below. - // This avoids snapshot-clearing errors in LinksUpdate::acquirePageLock(). - $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket ); - - foreach ( $updates as $update ) { - // Carry over cause in case so the update can do extra logging - $update->setCause( $this->params['causeAction'], $this->params['causeAgent'] ); - // FIXME: This code probably shouldn't be here? - // Needed by things like Echo notifications which need - // to know which user caused the links update - if ( $update instanceof LinksUpdate ) { - $update->setRevision( $revision ); - if ( !empty( $this->params['triggeringUser'] ) ) { - $userInfo = $this->params['triggeringUser']; - if ( $userInfo['userId'] ) { - $user = User::newFromId( $userInfo['userId'] ); - } else { - // Anonymous, use the username - $user = User::newFromName( $userInfo['userName'], false ); - } - $update->setTriggeringUser( $user ); - } + $options = [ + 'recursive' => !empty( $this->params['useRecursiveLinksUpdate'] ), + // Carry over cause so the update can do extra logging + 'causeAction' => $this->params['causeAction'], + 'causeAgent' => $this->params['causeAgent'], + 'defer' => false, + 'transactionTicket' => $ticket, + ]; + if ( !empty( $this->params['triggeringUser'] ) ) { + $userInfo = $this->params['triggeringUser']; + if ( $userInfo['userId'] ) { + $options['triggeringUser'] = User::newFromId( $userInfo['userId'] ); + } else { + // Anonymous, use the username + $options['triggeringUser'] = User::newFromName( $userInfo['userName'], false ); } } - - foreach ( $updates as $update ) { - $update->setTransactionTicket( $ticket ); - $update->doUpdate(); - } + $page->doSecondaryDataUpdates( $options ); InfoAction::invalidateCache( $title );