MediaWiki
REL1_21
|
00001 <?php 00028 require_once( __DIR__ . '/Maintenance.php' ); 00029 00035 class RunJobs extends Maintenance { 00036 public function __construct() { 00037 parent::__construct(); 00038 $this->mDescription = "Run pending jobs"; 00039 $this->addOption( 'maxjobs', 'Maximum number of jobs to run', false, true ); 00040 $this->addOption( 'maxtime', 'Maximum amount of wall-clock time', false, true ); 00041 $this->addOption( 'type', 'Type of job to run', false, true ); 00042 $this->addOption( 'procs', 'Number of processes to use', false, true ); 00043 } 00044 00045 public function memoryLimit() { 00046 if ( $this->hasOption( 'memory-limit' ) ) { 00047 return parent::memoryLimit(); 00048 } 00049 // Don't eat all memory on the machine if we get a bad job. 00050 return "150M"; 00051 } 00052 00053 public function execute() { 00054 global $wgTitle; 00055 00056 if ( wfReadOnly() ) { 00057 $this->error( "Unable to run jobs; the wiki is in read-only mode.", 1 ); // die 00058 } 00059 00060 if ( $this->hasOption( 'procs' ) ) { 00061 $procs = intval( $this->getOption( 'procs' ) ); 00062 if ( $procs < 1 || $procs > 1000 ) { 00063 $this->error( "Invalid argument to --procs", true ); 00064 } 00065 $fc = new ForkController( $procs ); 00066 if ( $fc->start() != 'child' ) { 00067 exit( 0 ); 00068 } 00069 } 00070 $maxJobs = $this->getOption( 'maxjobs', false ); 00071 $maxTime = $this->getOption( 'maxtime', false ); 00072 $startTime = time(); 00073 $type = $this->getOption( 'type', false ); 00074 $wgTitle = Title::newFromText( 'RunJobs.php' ); 00075 $dbw = wfGetDB( DB_MASTER ); 00076 $jobsRun = 0; // counter 00077 00078 $group = JobQueueGroup::singleton(); 00079 // Handle any required periodic queue maintenance 00080 $count = $group->executeReadyPeriodicTasks(); 00081 if ( $count > 0 ) { 00082 $this->runJobsLog( "Executed $count periodic queue task(s)." ); 00083 } 00084 00085 $lastTime = time(); 00086 do { 00087 $job = ( $type === false ) 00088 ? $group->pop( JobQueueGroup::TYPE_DEFAULT, JobQueueGroup::USE_CACHE ) 00089 : $group->pop( $type ); // job from a single queue 00090 if ( $job ) { // found a job 00091 ++$jobsRun; 00092 $this->runJobsLog( $job->toString() . " STARTING" ); 00093 00094 // Run the job... 00095 $t = microtime( true ); 00096 try { 00097 $status = $job->run(); 00098 $error = $job->getLastError(); 00099 } catch ( MWException $e ) { 00100 $status = false; 00101 $error = get_class( $e ) . ': ' . $e->getMessage(); 00102 } 00103 $timeMs = intval( ( microtime( true ) - $t ) * 1000 ); 00104 00105 // Mark the job as done on success or when the job cannot be retried 00106 if ( $status !== false || !$job->allowRetries() ) { 00107 $group->ack( $job ); // done 00108 } 00109 00110 if ( !$status ) { 00111 $this->runJobsLog( $job->toString() . " t=$timeMs error={$error}" ); 00112 } else { 00113 $this->runJobsLog( $job->toString() . " t=$timeMs good" ); 00114 } 00115 00116 // Break out if we hit the job count or wall time limits... 00117 if ( $maxJobs && $jobsRun >= $maxJobs ) { 00118 break; 00119 } elseif ( $maxTime && ( time() - $startTime ) > $maxTime ) { 00120 break; 00121 } 00122 00123 // Don't let any of the main DB slaves get backed up 00124 $timePassed = time() - $lastTime; 00125 if ( $timePassed >= 5 || $timePassed < 0 ) { 00126 wfWaitForSlaves(); 00127 } 00128 // Don't let any queue slaves/backups fall behind 00129 if ( $jobsRun > 0 && ( $jobsRun % 100 ) == 0 ) { 00130 $group->waitForBackups(); 00131 } 00132 } 00133 } while ( $job ); // stop when there are no jobs 00134 } 00135 00140 private function runJobsLog( $msg ) { 00141 $this->output( wfTimestamp( TS_DB ) . " $msg\n" ); 00142 wfDebugLog( 'runJobs', $msg ); 00143 } 00144 } 00145 00146 $maintClass = "RunJobs"; 00147 require_once( RUN_MAINTENANCE_IF_MAIN );