Use AutoCommitUpdate instead of Database->onTransactionIdle
authorSeb35 <seb35@seb35.fr>
Thu, 1 Jun 2017 15:49:28 +0000 (17:49 +0200)
committerSeb35 <seb35@seb35.fr>
Tue, 6 Jun 2017 12:23:37 +0000 (14:23 +0200)
This is needed for deferred updates LinksDeletionUpdate and LinksUpdate, else
callbacks registered with onTransactionIdle prevent other transactions from
being executed, at least in this case.

Bug: T154425
Bug: T154438
Bug: T157679
Change-Id: Iecd396d584a62ac936cd963915339159467b44cd

includes/MediaWiki.php
includes/jobqueue/JobQueueDB.php
includes/jobqueue/JobQueueGroup.php
includes/jobqueue/JobRunner.php

index a7214c7..2125c23 100644 (file)
@@ -898,12 +898,13 @@ class MediaWiki {
                        __METHOD__
                );
 
+               // Push lazilly-pushed jobs
+               // Important: this must be the last deferred update added (T100085, T154425)
+               DeferredUpdates::addCallableUpdate( [ 'JobQueueGroup', 'pushLazyJobs' ] );
+
                // Do any deferred jobs
                DeferredUpdates::doUpdates( 'enqueue' );
 
-               // Make sure any lazy jobs are pushed
-               JobQueueGroup::pushLazyJobs();
-
                // Now that everything specific to this request is done,
                // try to occasionally run jobs (if enabled) from the queues
                if ( $mode === 'normal' ) {
index 924aacc..5e45730 100644 (file)
@@ -185,15 +185,13 @@ class JobQueueDB extends JobQueue {
         * @return void
         */
        protected function doBatchPush( array $jobs, $flags ) {
-               $dbw = $this->getMasterDB();
-
-               $method = __METHOD__;
-               $dbw->onTransactionIdle(
-                       function () use ( $dbw, $jobs, $flags, $method ) {
-                               $this->doBatchPushInternal( $dbw, $jobs, $flags, $method );
-                       },
-                       __METHOD__
-               );
+               DeferredUpdates::addUpdate( new AutoCommitUpdate(
+                       wfGetDB( DB_MASTER ),
+                       __METHOD__,
+                       function ( IDatabase $dbw, $fname ) use ( $jobs, $flags ) {
+                               $this->doBatchPushInternal( $dbw, $jobs, $flags, $fname );
+                       }
+               ) );
        }
 
        /**
index 9f78404..5d5ea26 100644 (file)
@@ -163,7 +163,9 @@ class JobQueueGroup {
        /**
         * Buffer jobs for insertion via push() or call it now if in CLI mode
         *
-        * Note that MediaWiki::restInPeace() calls pushLazyJobs()
+        * Note that pushLazyJobs() is registered as a deferred update just before
+        * DeferredUpdates::doUpdates() in MediaWiki and JobRunner classes in order
+        * to be executed as the very last deferred update (T100085, T154425).
         *
         * @param IJobSpecification|IJobSpecification[] $jobs A single Job or a list of Jobs
         * @return void
index a1aeaba..0a0e9e0 100644 (file)
@@ -289,10 +289,11 @@ class JobRunner implements LoggerAwareInterface {
                        $status = $job->run();
                        $error = $job->getLastError();
                        $this->commitMasterChanges( $lbFactory, $job, $fnameTrxOwner );
+                       // Push lazilly-pushed jobs
+                       // Important: this must be the last deferred update added (T100085, T154425)
+                       DeferredUpdates::addCallableUpdate( [ 'JobQueueGroup', 'pushLazyJobs' ] );
                        // 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;