Better handling of jobs execution in post-connection shutdown
authorSeb35 <seb35@seb35.fr>
Mon, 29 May 2017 22:58:56 +0000 (00:58 +0200)
committerSeb35 <seb35@seb35.fr>
Thu, 1 Jun 2017 11:16:08 +0000 (13:16 +0200)
In the postprocessing, some jobs can be executed but given the deferred
updates were already "closed", any new DeferredUpdate were directly called
(as explained by Krinkle on T165714), and the transactions opened by
classical jobs are badly mixed with transactions (directly) executed by
DeferredUpdates jobs, issuing a DBError, avoiding the job, which stays
in a 'claimed' status even if failed.

Quite similarly, some DeferredUpdates callables use JobQueueGroup::lazyPush
so it is needed to really push the generated jobs.

This change removes the run-immediately-deferred-updates behaviour even
in the post-connection shutdown, and given there is a call to
DeferredUpdates::doUpdates in JobRunner::execute it is not necessary to
add another one and hence execution of Web jobs is more similar to execution
of CLI jobs. In the same spirit to reconcile Web jobs and CLI jobs, the
call to JobQueueGroup::pushLazyJobs is done in JobRunner::execute.

Bug: T165714
Bug: T100085
Change-Id: I721e7167eca5b0b6227234fe516005243ab22388

includes/MediaWiki.php
includes/deferred/DeferredUpdates.php
includes/jobqueue/JobRunner.php

index b18414d..a7214c7 100644 (file)
@@ -900,7 +900,6 @@ class MediaWiki {
 
                // Do any deferred jobs
                DeferredUpdates::doUpdates( 'enqueue' );
-               DeferredUpdates::setImmediateMode( true );
 
                // Make sure any lazy jobs are pushed
                JobQueueGroup::pushLazyJobs();
index bbe8687..9f5b31a 100644 (file)
@@ -55,8 +55,6 @@ class DeferredUpdates {
        private static $preSendUpdates = [];
        /** @var DeferrableUpdate[] Updates to be deferred until after request end */
        private static $postSendUpdates = [];
-       /** @var bool Whether to just run updates in addUpdate() */
-       private static $immediateMode = false;
 
        const ALL = 0; // all updates; in web requests, use only after flushing the output buffer
        const PRESEND = 1; // for updates that should run before flushing output buffer
@@ -90,12 +88,6 @@ class DeferredUpdates {
                        self::push( self::$postSendUpdates, $update );
                }
 
-               if ( self::$immediateMode ) {
-                       // No more explicit doUpdates() calls will happen, so run this now
-                       self::doUpdates( 'run' );
-                       return;
-               }
-
                // Try to run the updates now if in CLI mode and no transaction is active.
                // This covers scripts that don't/barely use the DB but make updates to other stores.
                if ( $wgCommandLineMode ) {
@@ -140,9 +132,10 @@ class DeferredUpdates {
        /**
         * @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 ) {
-               self::$immediateMode = (bool)$value;
+               wfDeprecated( __METHOD__, '1.29' );
        }
 
        /**
index 6415533..a1aeaba 100644 (file)
@@ -291,6 +291,8 @@ class JobRunner implements LoggerAwareInterface {
                        $this->commitMasterChanges( $lbFactory, $job, $fnameTrxOwner );
                        // Run any deferred update tasks; doUpdates() manages transactions itself
                        DeferredUpdates::doUpdates();
+                       // Push lazy jobs added by the job or its deferred udpates
+                       JobQueueGroup::pushLazyJobs();
                } catch ( Exception $e ) {
                        MWExceptionHandler::rollbackMasterChangesAndLog( $e );
                        $status = false;