*
* @file
*/
+use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\LBFactory;
+use Wikimedia\Rdbms\LoadBalancer;
/**
* Class for managing the deferred updates
}
}
+ /**
+ * @param bool $value Whether to just immediately run updates in addUpdate()
+ * @since 1.28
+ * @deprecated 1.29 Causes issues in Web-executed jobs - see T165714 and T100085.
+ */
+ public static function setImmediateMode( $value ) {
+ wfDeprecated( __METHOD__, '1.29' );
+ }
+
/**
* @param DeferrableUpdate[] $queue
* @param DeferrableUpdate $update
}
/**
+ * Immediately run/queue a list of updates
+ *
* @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)
* @throws ErrorPageError Happens on top-level calls
* @throws Exception Happens on second-level calls
*/
- public static function execute( array &$queue, $mode, $stage ) {
+ protected static function execute( array &$queue, $mode, $stage ) {
$services = MediaWikiServices::getInstance();
$stats = $services->getStatsdDataFactory();
$lbFactory = $services->getDBLoadBalancerFactory();
$method = RequestContext::getMain()->getRequest()->getMethod();
+ $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
+
/** @var ErrorPageError $reportableError */
$reportableError = null;
/** @var DeferrableUpdate[] $updates Snapshot of queue */
// Order will be DataUpdate followed by generic DeferrableUpdate tasks
$updatesByType = [ 'data' => [], 'generic' => [] ];
foreach ( $updates as $du ) {
- $updatesByType[$du instanceof DataUpdate ? 'data' : 'generic'][] = $du;
+ if ( $du instanceof DataUpdate ) {
+ $du->setTransactionTicket( $ticket );
+ $updatesByType['data'][] = $du;
+ } else {
+ $updatesByType['generic'][] = $du;
+ }
+
$name = ( $du instanceof DeferrableCallback )
? get_class( $du ) . '-' . $du->getOrigin()
: get_class( $du );
$firstKey = key( self::$executeContext['subqueue'] );
unset( self::$executeContext['subqueue'][$firstKey] );
+ if ( $subUpdate instanceof DataUpdate ) {
+ $subUpdate->setTransactionTicket( $ticket );
+ }
+
$guiError = self::runUpdate( $subUpdate, $lbFactory, $stage );
$reportableError = $reportableError ?: $guiError;
}
return count( self::$preSendUpdates ) + count( self::$postSendUpdates );
}
+ /**
+ * @param integer $stage DeferredUpdates constant (PRESEND, POSTSEND, or ALL)
+ * @since 1.29
+ */
+ public static function getPendingUpdates( $stage = self::ALL ) {
+ $updates = [];
+ if ( $stage === self::ALL || $stage === self::PRESEND ) {
+ $updates = array_merge( $updates, self::$preSendUpdates );
+ }
+ if ( $stage === self::ALL || $stage === self::POSTSEND ) {
+ $updates = array_merge( $updates, self::$postSendUpdates );
+ }
+ return $updates;
+ }
+
/**
* Clear all pending updates without performing them. Generally, you don't
* want or need to call this. Unit tests need it though.