X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fdeferred%2FDeferredUpdates.php;h=40069f33c0c665a50748bb1aa832d05b102a6b78;hb=51690a5c79cc2ad8ee35ef8f728ccb1b70298ce1;hp=a3a37f6f2ee712158a477ea93fab54e20a71b090;hpb=dae4c94d893057345f62a3d498fb85c0a54de5a6;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/deferred/DeferredUpdates.php b/includes/deferred/DeferredUpdates.php index a3a37f6f2e..40069f33c0 100644 --- a/includes/deferred/DeferredUpdates.php +++ b/includes/deferred/DeferredUpdates.php @@ -71,14 +71,17 @@ class DeferredUpdates { * In CLI mode, callback magic will also be used to run updates when safe * * @param DeferrableUpdate $update Some object that implements doUpdate() - * @param integer $stage DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27) + * @param int $stage DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27) */ public static function addUpdate( DeferrableUpdate $update, $stage = self::POSTSEND ) { global $wgCommandLineMode; - // This is a sub-DeferredUpdate, run it right after its parent update if ( self::$executeContext && self::$executeContext['stage'] >= $stage ) { + // This is a sub-DeferredUpdate; run it right after its parent update. + // Also, while post-send updates are running, push any "pre-send" jobs to the + // active post-send queue to make sure they get run this round (or at all). self::$executeContext['subqueue'][] = $update; + return; } @@ -102,7 +105,7 @@ class DeferredUpdates { * @see MWCallableUpdate::__construct() * * @param callable $callable - * @param integer $stage DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27) + * @param int $stage DeferredUpdates constant (PRESEND or POSTSEND) (since 1.27) * @param IDatabase|null $dbw Abort if this DB is rolled back [optional] (since 1.28) */ public static function addCallableUpdate( @@ -115,7 +118,7 @@ class DeferredUpdates { * Do any deferred updates and clear the list * * @param string $mode Use "enqueue" to use the job queue when possible [Default: "run"] - * @param integer $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL) (since 1.27) + * @param int $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL) (since 1.27) */ public static function doUpdates( $mode = 'run', $stage = self::ALL ) { $stageEffective = ( $stage === self::ALL ) ? self::POSTSEND : $stage; @@ -162,7 +165,7 @@ class DeferredUpdates { * * @param DeferrableUpdate[] &$queue List of DeferrableUpdate objects * @param string $mode Use "enqueue" to use the job queue when possible - * @param integer $stage Class constant (PRESEND, POSTSEND) (since 1.28) + * @param int $stage Class constant (PRESEND, POSTSEND) (since 1.28) * @throws ErrorPageError Happens on top-level calls * @throws Exception Happens on second-level calls */ @@ -183,16 +186,6 @@ class DeferredUpdates { while ( $updates ) { $queue = []; // clear the queue - if ( $mode === 'enqueue' ) { - try { - // Push enqueuable updates to the job queue and get the rest - $updates = self::enqueueUpdates( $updates ); - } catch ( Exception $e ) { - // Let other updates have a chance to run if this failed - MWExceptionHandler::rollbackMasterChangesAndLog( $e ); - } - } - // Order will be DataUpdate followed by generic DeferrableUpdate tasks $updatesByType = [ 'data' => [], 'generic' => [] ]; foreach ( $updates as $du ) { @@ -212,13 +205,9 @@ class DeferredUpdates { // Execute all remaining tasks... foreach ( $updatesByType as $updatesForType ) { foreach ( $updatesForType as $update ) { - self::$executeContext = [ - 'update' => $update, - 'stage' => $stage, - 'subqueue' => [] - ]; + self::$executeContext = [ 'stage' => $stage, 'subqueue' => [] ]; /** @var DeferrableUpdate $update */ - $guiError = self::runUpdate( $update, $lbFactory, $stage ); + $guiError = self::runUpdate( $update, $lbFactory, $mode, $stage ); $reportableError = $reportableError ?: $guiError; // Do the subqueue updates for $update until there are none while ( self::$executeContext['subqueue'] ) { @@ -230,7 +219,7 @@ class DeferredUpdates { $subUpdate->setTransactionTicket( $ticket ); } - $guiError = self::runUpdate( $subUpdate, $lbFactory, $stage ); + $guiError = self::runUpdate( $subUpdate, $lbFactory, $mode, $stage ); $reportableError = $reportableError ?: $guiError; } self::$executeContext = null; @@ -248,16 +237,26 @@ class DeferredUpdates { /** * @param DeferrableUpdate $update * @param LBFactory $lbFactory - * @param integer $stage + * @param string $mode + * @param int $stage * @return ErrorPageError|null */ - private static function runUpdate( DeferrableUpdate $update, LBFactory $lbFactory, $stage ) { + private static function runUpdate( + DeferrableUpdate $update, LBFactory $lbFactory, $mode, $stage + ) { $guiError = null; try { - $fnameTrxOwner = get_class( $update ) . '::doUpdate'; - $lbFactory->beginMasterChanges( $fnameTrxOwner ); - $update->doUpdate(); - $lbFactory->commitMasterChanges( $fnameTrxOwner ); + if ( $mode === 'enqueue' && $update instanceof EnqueueableDataUpdate ) { + // Run only the job enqueue logic to complete the update later + $spec = $update->getAsJobSpecification(); + JobQueueGroup::singleton( $spec['wiki'] )->push( $spec['job'] ); + } else { + // Run the bulk of the update now + $fnameTrxOwner = get_class( $update ) . '::doUpdate'; + $lbFactory->beginMasterChanges( $fnameTrxOwner ); + $update->doUpdate(); + $lbFactory->commitMasterChanges( $fnameTrxOwner ); + } } catch ( Exception $e ) { // Reporting GUI exceptions does not work post-send if ( $e instanceof ErrorPageError && $stage === self::PRESEND ) { @@ -323,7 +322,7 @@ class DeferredUpdates { } /** - * @return integer Number of enqueued updates + * @return int Number of enqueued updates * @since 1.28 */ public static function pendingUpdatesCount() { @@ -331,7 +330,7 @@ class DeferredUpdates { } /** - * @param integer $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL) + * @param int $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL) * @return DeferrableUpdate[] * @since 1.29 */