Merge "Add List-Unsubscribe header to emails"
[lhc/web/wiklou.git] / includes / jobqueue / JobRunner.php
index 0948092..bb12298 100644 (file)
@@ -103,23 +103,16 @@ class JobRunner implements LoggerAwareInterface {
                        return $response;
                }
 
-               $group = JobQueueGroup::singleton();
-               // Handle any required periodic queue maintenance
-               $count = $group->executeReadyPeriodicTasks();
-               if ( $count > 0 ) {
-                       $msg = "Executed $count periodic queue task(s).";
-                       $this->logger->debug( $msg );
-                       $this->debugCallback( $msg );
-               }
-
                // Bail out if in read-only mode
                if ( wfReadOnly() ) {
                        $response['reached'] = 'read-only';
                        return $response;
                }
 
+               $profiler = Profiler::instance();
+
                // Catch huge single updates that lead to slave lag
-               $trxProfiler = Profiler::instance()->getTransactionProfiler();
+               $trxProfiler = $profiler->getTransactionProfiler();
                $trxProfiler->setLogger( LoggerFactory::getInstance( 'DBPerformance' ) );
                $trxProfiler->setExpectations( $wgTrxProfilerLimits['JobRunner'], __METHOD__ );
 
@@ -132,8 +125,10 @@ class JobRunner implements LoggerAwareInterface {
                        return $response;
                }
 
+               $group = JobQueueGroup::singleton();
+               
                // Flush any pending DB writes for sanity
-               wfGetLBFactory()->commitMasterChanges();
+               wfGetLBFactory()->commitAll();
 
                // Some jobs types should not run until a certain timestamp
                $backoffs = array(); // map of (type => UNIX expiry)
@@ -175,24 +170,37 @@ class JobRunner implements LoggerAwareInterface {
                                }
 
                                $msg = $job->toString() . " STARTING";
-                               $this->logger->info( $msg );
+                               $this->logger->debug( $msg );
                                $this->debugCallback( $msg );
 
                                // Run the job...
+                               $psection = $profiler->scopedProfileIn( __METHOD__ . '-' . $jType );
                                $jobStartTime = microtime( true );
                                try {
                                        ++$jobsRun;
                                        $status = $job->run();
                                        $error = $job->getLastError();
                                        $this->commitMasterChanges( $job );
+
+                                       DeferredUpdates::doUpdates();
+                                       $this->commitMasterChanges( $job );
                                } catch ( Exception $e ) {
                                        MWExceptionHandler::rollbackMasterChangesAndLog( $e );
                                        $status = false;
                                        $error = get_class( $e ) . ': ' . $e->getMessage();
                                        MWExceptionHandler::logException( $e );
                                }
+                               // Commit all outstanding connections that are in a transaction
+                               // to get a fresh repeatable read snapshot on every connection.
+                               // This is important because if you have an old snapshot on the
+                               // database you could run the job incorrectly. Its possible, for
+                               // example, to pick up a RefreshLinksJob for a new page that isn't
+                               // even visible to the snapshot. The snapshot could have been
+                               // created before the page. Fresh snapshots will see the page.
+                               wfGetLBFactory()->commitAll();
                                $timeMs = intval( ( microtime( true ) - $jobStartTime ) * 1000 );
                                $timeMsTotal += $timeMs;
+                               $profiler->scopedProfileOut( $psection );
 
                                // Mark the job as done on success or when the job cannot be retried
                                if ( $status !== false || !$job->allowRetries() ) {
@@ -410,7 +418,10 @@ class JobRunner implements LoggerAwareInterface {
        }
 
        /**
-        * Commit any DB master changes from a job on all load balancers
+        * Issue a commit on all masters who are currently in a transaction and have
+        * made changes to the database. It also supports sometimes waiting for the
+        * local wiki's slaves to catch up. See the documentation for
+        * $wgJobSerialCommitThreshold for more.
         *
         * @param Job $job
         * @throws DBError