public static function addUpdate( DeferrableUpdate $update, $stage = self::POSTSEND ) {
global $wgCommandLineMode;
- if ( self::$executeContext && self::$executeContext['stage'] >= $stage ) {
+ if (
+ self::$executeContext &&
+ self::$executeContext['stage'] >= $stage &&
+ !( $update instanceof MergeableUpdate )
+ ) {
// 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).
/**
* Do any deferred updates and clear the list
*
+ * If $stage is self::ALL then the queue of PRESEND updates will be resolved,
+ * followed by the queue of POSTSEND updates
+ *
* @param string $mode Use "enqueue" to use the job queue when possible [Default: "run"]
* @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;
+ // For ALL mode, make sure that any PRESEND updates added along the way get run.
+ // Normally, these use the subqueue, but that isn't true for MergeableUpdate items.
+ do {
+ if ( $stage === self::ALL || $stage === self::PRESEND ) {
+ self::execute( self::$preSendUpdates, $mode, $stageEffective );
+ }
- if ( $stage === self::ALL || $stage === self::PRESEND ) {
- self::execute( self::$preSendUpdates, $mode, $stageEffective );
- }
-
- if ( $stage === self::ALL || $stage == self::POSTSEND ) {
- self::execute( self::$postSendUpdates, $mode, $stageEffective );
- }
+ if ( $stage === self::ALL || $stage == self::POSTSEND ) {
+ self::execute( self::$postSendUpdates, $mode, $stageEffective );
+ }
+ } while ( $stage === self::ALL && self::$preSendUpdates );
}
/**
/** @var MergeableUpdate $existingUpdate */
$existingUpdate = $queue[$class];
$existingUpdate->merge( $update );
+ // Move the update to the end to handle things like mergeable purge
+ // updates that might depend on the prior updates in the queue running
+ unset( $queue[$class] );
+ $queue[$class] = $existingUpdate;
} else {
$queue[$class] = $update;
}