MediaWiki master
runJobs.php
Go to the documentation of this file.
1<?php
10// @codeCoverageIgnoreStart
11require_once __DIR__ . '/Maintenance.php';
12// @codeCoverageIgnoreEnd
13
18
24class RunJobs extends Maintenance {
25 public function __construct() {
26 parent::__construct();
27 $this->addDescription( 'Run pending jobs' );
28 $this->addOption( 'maxjobs', 'Maximum number of jobs to run', false, true );
29 $this->addOption( 'maxtime', 'Maximum amount of wall-clock time', false, true );
30 $this->addOption( 'type', 'Type of job to run', false, true );
31 $this->addOption( 'procs', 'Number of processes to use', false, true );
32 $this->addOption( 'nothrottle', 'Ignore job throttling configuration', false, false );
33 $this->addOption( 'result', 'Set to "json" to print only a JSON response', false, true );
34 $this->addOption( 'wait', 'Wait for new jobs instead of exiting', false, false );
35 }
36
37 public function finalSetup( SettingsBuilder $settingsBuilder ) {
38 // So extensions (and other code) can check whether they're running in job mode.
39 // This is not defined if this script is included from installer/updater or phpunit.
40 define( 'MEDIAWIKI_JOB_RUNNER', true );
41 parent::finalSetup( $settingsBuilder );
42 }
43
45 public function memoryLimit() {
46 if ( $this->hasOption( 'memory-limit' ) ) {
47 return parent::memoryLimit();
48 }
49
50 // Don't eat all memory on the machine if we get a bad job.
51 //
52 // The default memory_limit for PHP-CLI is -1 (unlimited).
53 // This is fine for most maintenance scripts, but runJobs.php is unusually likely
54 // to leak memory (e.g. some badly-managed in-process cache array in some class)
55 // because it can run for long periods doing different tasks.
56 // Let's use 3x the limit for a web request.
57 global $wgMemoryLimit;
58 $limit = wfShorthandToInteger( (string)$wgMemoryLimit );
59 return $limit === -1 ? $limit : ( $limit * 3 );
60 }
61
62 public function execute() {
63 if ( $this->hasOption( 'procs' ) ) {
64 $procs = intval( $this->getOption( 'procs' ) );
65 if ( $procs < 1 || $procs > 1000 ) {
66 $this->fatalError( "Invalid argument to --procs" );
67 } elseif ( $procs != 1 ) {
68 try {
69 $fc = new ForkController( $procs );
70 } catch ( Throwable $e ) {
71 $this->fatalError( $e->getMessage() );
72 }
73 if ( $fc->start() != 'child' ) {
74 return;
75 }
76 }
77 }
78
79 $outputJSON = ( $this->getOption( 'result' ) === 'json' );
80 $wait = $this->hasOption( 'wait' );
81
82 $runner = $this->getServiceContainer()->getJobRunner();
83 if ( !$outputJSON ) {
84 $runner->setDebugHandler( $this->debugInternal( ... ) );
85 }
86
87 $type = $this->getOption( 'type', false );
88 $maxJobs = $this->getOption( 'maxjobs', false );
89 $maxTime = $this->getOption( 'maxtime', false );
90 $throttle = !$this->hasOption( 'nothrottle' );
91
92 while ( true ) {
93 $response = $runner->run( [
94 'type' => $type,
95 'maxJobs' => $maxJobs,
96 'maxTime' => $maxTime,
97 'throttle' => $throttle,
98 ] );
99
100 if ( $outputJSON ) {
101 $this->output( FormatJson::encode( $response, true ) );
102 }
103
104 if (
105 !$wait ||
106 $response['reached'] === 'time-limit' ||
107 $response['reached'] === 'job-limit' ||
108 $response['reached'] === 'memory-limit' ||
109 $response['reached'] === 'exception'
110 ) {
111 // If job queue is empty, output it
112 if ( !$outputJSON && $response['jobs'] === [] ) {
113 $this->output( "Job queue is empty.\n" );
114 }
115 break;
116 }
117
118 if ( $maxJobs !== false ) {
119 $maxJobs -= count( $response['jobs'] );
120 }
121
122 sleep( 1 );
123 }
124 }
125
129 private function debugInternal( $s ) {
130 $this->output( $s );
131 }
132}
133
134// @codeCoverageIgnoreStart
135$maintClass = RunJobs::class;
136require_once RUN_MAINTENANCE_IF_MAIN;
137// @codeCoverageIgnoreEnd
wfShorthandToInteger(?string $string='', int $default=-1)
Converts shorthand byte notation to integer form.
JSON formatter wrapper class.
Manage forking inside CLI maintenance scripts.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
output( $out, $channel=null)
Throw some output to the user.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
hasOption( $name)
Checks to see if a particular option was set.
getOption( $name, $default=null)
Get an option, or return the default.
getServiceContainer()
Returns the main service container.
addDescription( $text)
Set the description text.
Builder class for constructing a Config object from a set of sources during bootstrap.
Maintenance script that runs pending jobs.
Definition runJobs.php:24
execute()
Do the actual work.
Definition runJobs.php:62
memoryLimit()
Override memory_limit from php.ini on maintenance scripts.This defaults to max/unlimited,...
Definition runJobs.php:45
__construct()
Default constructor.
Definition runJobs.php:25
finalSetup(SettingsBuilder $settingsBuilder)
Handle some last-minute setup here.
Definition runJobs.php:37
$wgMemoryLimit
Config variable stub for the MemoryLimit setting, for use by phpdoc and IDEs.
$runner
$maintClass
Definition runJobs.php:135