summaryrefslogtreecommitdiff
path: root/maintenance/runJobs.php
diff options
context:
space:
mode:
Diffstat (limited to 'maintenance/runJobs.php')
-rw-r--r--maintenance/runJobs.php54
1 files changed, 44 insertions, 10 deletions
diff --git a/maintenance/runJobs.php b/maintenance/runJobs.php
index b1be714c..429edf42 100644
--- a/maintenance/runJobs.php
+++ b/maintenance/runJobs.php
@@ -25,7 +25,7 @@
* @ingroup Maintenance
*/
-require_once( __DIR__ . '/Maintenance.php' );
+require_once __DIR__ . '/Maintenance.php';
/**
* Maintenance script that runs pending jobs.
@@ -61,10 +61,11 @@ class RunJobs extends Maintenance {
$procs = intval( $this->getOption( 'procs' ) );
if ( $procs < 1 || $procs > 1000 ) {
$this->error( "Invalid argument to --procs", true );
- }
- $fc = new ForkController( $procs );
- if ( $fc->start() != 'child' ) {
- exit( 0 );
+ } elseif ( $procs != 1 ) {
+ $fc = new ForkController( $procs );
+ if ( $fc->start() != 'child' ) {
+ exit( 0 );
+ }
}
}
$maxJobs = $this->getOption( 'maxjobs', false );
@@ -72,7 +73,6 @@ class RunJobs extends Maintenance {
$startTime = time();
$type = $this->getOption( 'type', false );
$wgTitle = Title::newFromText( 'RunJobs.php' );
- $dbw = wfGetDB( DB_MASTER );
$jobsRun = 0; // counter
$group = JobQueueGroup::singleton();
@@ -82,16 +82,20 @@ class RunJobs extends Maintenance {
$this->runJobsLog( "Executed $count periodic queue task(s)." );
}
- $lastTime = time();
+ $flags = JobQueueGroup::USE_CACHE | JobQueueGroup::USE_PRIORITY;
+ $lastTime = time(); // time since last slave check
do {
$job = ( $type === false )
- ? $group->pop( JobQueueGroup::TYPE_DEFAULT, JobQueueGroup::USE_CACHE )
+ ? $group->pop( JobQueueGroup::TYPE_DEFAULT, $flags )
: $group->pop( $type ); // job from a single queue
if ( $job ) { // found a job
++$jobsRun;
$this->runJobsLog( $job->toString() . " STARTING" );
+ // Set timer to stop the job if too much CPU time is used
+ set_time_limit( $maxTime ?: 0 );
// Run the job...
+ wfProfileIn( __METHOD__ . '-' . get_class( $job ) );
$t = microtime( true );
try {
$status = $job->run();
@@ -99,15 +103,19 @@ class RunJobs extends Maintenance {
} catch ( MWException $e ) {
$status = false;
$error = get_class( $e ) . ': ' . $e->getMessage();
+ $e->report(); // write error to STDERR and the log
}
$timeMs = intval( ( microtime( true ) - $t ) * 1000 );
+ wfProfileOut( __METHOD__ . '-' . get_class( $job ) );
+ // Disable the timer
+ set_time_limit( 0 );
// Mark the job as done on success or when the job cannot be retried
if ( $status !== false || !$job->allowRetries() ) {
$group->ack( $job ); // done
}
- if ( !$status ) {
+ if ( $status === false ) {
$this->runJobsLog( $job->toString() . " t=$timeMs error={$error}" );
} else {
$this->runJobsLog( $job->toString() . " t=$timeMs good" );
@@ -124,16 +132,42 @@ class RunJobs extends Maintenance {
$timePassed = time() - $lastTime;
if ( $timePassed >= 5 || $timePassed < 0 ) {
wfWaitForSlaves();
+ $lastTime = time();
}
// Don't let any queue slaves/backups fall behind
if ( $jobsRun > 0 && ( $jobsRun % 100 ) == 0 ) {
$group->waitForBackups();
}
+
+ // Bail if near-OOM instead of in a job
+ $this->assertMemoryOK();
}
} while ( $job ); // stop when there are no jobs
}
/**
+ * Make sure that this script is not too close to the memory usage limit
+ * @throws MWException
+ */
+ private function assertMemoryOK() {
+ static $maxBytes = null;
+ if ( $maxBytes === null ) {
+ $m = array();
+ if ( preg_match( '!^(\d+)(k|m|g|)$!i', ini_get( 'memory_limit' ), $m ) ) {
+ list( , $num, $unit ) = $m;
+ $conv = array( 'g' => 1024 * 1024 * 1024, 'm' => 1024 * 1024, 'k' => 1024, '' => 1 );
+ $maxBytes = $num * $conv[strtolower( $unit )];
+ } else {
+ $maxBytes = 0;
+ }
+ }
+ $usedBytes = memory_get_usage();
+ if ( $maxBytes && $usedBytes >= 0.95 * $maxBytes ) {
+ throw new MWException( "Detected excessive memory usage ($usedBytes/$maxBytes)." );
+ }
+ }
+
+ /**
* Log the job message
* @param $msg String The message to log
*/
@@ -144,4 +178,4 @@ class RunJobs extends Maintenance {
}
$maintClass = "RunJobs";
-require_once( RUN_MAINTENANCE_IF_MAIN );
+require_once RUN_MAINTENANCE_IF_MAIN;