If the user is not waiting at this point, so there is not much
reason to enqueue a job over just doing the work now. Running
the update now gives more immediate results however.
This has the effect of making LinksUpdate run post-send for
forward link updates, since the addUpdate() call in WikiPage uses
the default POSTSEND mode. These updates used to be synchronous
in the past, before proper post-send update support. With post-send
updates, there is not much benefit to using the job queue here.
If post-send updates are not supported, this will continue to
use the job queue.
If a caller needs such updates to enqueue post-send to avoid DB
updates on HTTP GET or if the update is too big to run outside of
JobRunner, it can always just use JobQueueGroup::lazyPush() with
a direct job object or JobSpecification.
Change-Id: Ibc4b1e17538cc8b1fba7d13759e1ebb83abed869
MWExceptionHandler::rollbackMasterChangesAndLog( $e );
}
MWExceptionHandler::rollbackMasterChangesAndLog( $e );
}
+ $blocksHttpClient = true;
// Defer everything else if possible...
// Defer everything else if possible...
- $callback = function () use ( $mode ) {
+ $callback = function () use ( $mode, &$blocksHttpClient ) {
- $this->restInPeace( $mode );
+ $this->restInPeace( $mode, $blocksHttpClient );
} catch ( Exception $e ) {
// If this is post-send, then displaying errors can cause broken HTML
MWExceptionHandler::rollbackMasterChangesAndLog( $e );
} catch ( Exception $e ) {
// If this is post-send, then displaying errors can cause broken HTML
MWExceptionHandler::rollbackMasterChangesAndLog( $e );
if ( function_exists( 'register_postsend_function' ) ) {
// https://github.com/facebook/hhvm/issues/1230
register_postsend_function( $callback );
if ( function_exists( 'register_postsend_function' ) ) {
// https://github.com/facebook/hhvm/issues/1230
register_postsend_function( $callback );
+ $blocksHttpClient = false;
} else {
if ( function_exists( 'fastcgi_finish_request' ) ) {
fastcgi_finish_request();
} else {
if ( function_exists( 'fastcgi_finish_request' ) ) {
fastcgi_finish_request();
+ $blocksHttpClient = false;
} else {
// Either all DB and deferred updates should happen or none.
// The latter should not be cancelled due to client disconnect.
} else {
// Either all DB and deferred updates should happen or none.
// The latter should not be cancelled due to client disconnect.
/**
* Ends this task peacefully
* @param string $mode Use 'fast' to always skip job running
/**
* Ends this task peacefully
* @param string $mode Use 'fast' to always skip job running
+ * @param bool $blocksHttpClient Whether this blocks an HTTP response to a client
- public function restInPeace( $mode = 'fast' ) {
+ public function restInPeace( $mode = 'fast', $blocksHttpClient = true ) {
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
// Assure deferred updates are not in the main transaction
$lbFactory->commitMasterChanges( __METHOD__ );
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
// Assure deferred updates are not in the main transaction
$lbFactory->commitMasterChanges( __METHOD__ );
// Important: this must be the last deferred update added (T100085, T154425)
DeferredUpdates::addCallableUpdate( [ JobQueueGroup::class, 'pushLazyJobs' ] );
// Important: this must be the last deferred update added (T100085, T154425)
DeferredUpdates::addCallableUpdate( [ JobQueueGroup::class, 'pushLazyJobs' ] );
- // Do any deferred jobs
- DeferredUpdates::doUpdates( 'enqueue' );
+ // Do any deferred jobs; preferring to run them now if a client will not wait on them
+ DeferredUpdates::doUpdates( $blocksHttpClient ? 'enqueue' : 'run' );
// Now that everything specific to this request is done,
// try to occasionally run jobs (if enabled) from the queues
// Now that everything specific to this request is done,
// try to occasionally run jobs (if enabled) from the queues