Tim Starling has submitted this change and it was merged.
Change subject: Changed on-request job running to shell out instead of doing a
loop.
......................................................................
Changed on-request job running to shell out instead of doing a loop.
* Also factored out a new wfShellExecDisabled() function.
* This will keep the process in the background if possible to avoid
killing site performance, especially with slow jobs.
* This also keep fatals and uncatcheable exceptions from
hitting the user.
* If $wgPhpCli is not set to an actual path or safe mode
is on, then the old code will be used.
Change-Id: I6a28152251659ee53eee2604f16d5bf02c85a44f
---
M includes/GlobalFunctions.php
M includes/Wiki.php
2 files changed, 56 insertions(+), 35 deletions(-)
Approvals:
Tim Starling: Verified; Looks good to me, approved
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index 458ab54..a81a338 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -2736,22 +2736,12 @@
}
/**
- * Execute a shell command, with time and memory limits mirrored from the PHP
- * configuration if supported.
- * @param string $cmd Command line, properly escaped for shell.
- * @param &$retval null|Mixed optional, will receive the program's exit code.
- * (non-zero is usually failure)
- * @param array $environ optional environment variables which should be
- * added to the executed command environment.
- * @param array $limits optional array with limits(filesize, memory, time,
walltime)
- * this overwrites the global wgShellMax* limits.
- * @return string collected stdout as a string (trailing newlines stripped)
+ * Check if wfShellExec() is effectively disabled via php.ini config
+ * @return bool|string False or one of (safemode,disabled)
+ * @since 1.22
*/
-function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits =
array() ) {
- global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
- $wgMaxShellWallClockTime, $wgShellCgroup;
-
- static $disabled;
+function wfShellExecDisabled() {
+ static $disabled = null;
if ( is_null( $disabled ) ) {
$disabled = false;
if ( wfIniGetBool( 'safe_mode' ) ) {
@@ -2767,6 +2757,26 @@
}
}
}
+ return $disabled;
+}
+
+/**
+ * Execute a shell command, with time and memory limits mirrored from the PHP
+ * configuration if supported.
+ * @param string $cmd Command line, properly escaped for shell.
+ * @param &$retval null|Mixed optional, will receive the program's exit code.
+ * (non-zero is usually failure)
+ * @param array $environ optional environment variables which should be
+ * added to the executed command environment.
+ * @param array $limits optional array with limits(filesize, memory, time,
walltime)
+ * this overwrites the global wgShellMax* limits.
+ * @return string collected stdout as a string (trailing newlines stripped)
+ */
+function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits =
array() ) {
+ global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
+ $wgMaxShellWallClockTime, $wgShellCgroup;
+
+ $disabled = wfShellExecDisabled();
if ( $disabled ) {
$retval = 1;
return $disabled == 'safemode' ?
diff --git a/includes/Wiki.php b/includes/Wiki.php
index 7d0d5af..2fd12d5 100644
--- a/includes/Wiki.php
+++ b/includes/Wiki.php
@@ -599,7 +599,7 @@
* Do a job from the job queue
*/
private function doJobs() {
- global $wgJobRunRate;
+ global $wgJobRunRate, $wgPhpCli, $IP;
if ( $wgJobRunRate <= 0 || wfReadOnly() ) {
return;
@@ -615,25 +615,36 @@
$n = intval( $wgJobRunRate );
}
- $group = JobQueueGroup::singleton();
- do {
- $job = $group->pop( JobQueueGroup::USE_CACHE ); // job
from any queue
- if ( $job ) {
- $output = $job->toString() . "\n";
- $t = - microtime( true );
- wfProfileIn( __METHOD__ . '-' . get_class( $job
) );
- $success = $job->run();
- wfProfileOut( __METHOD__ . '-' . get_class(
$job ) );
- $group->ack( $job ); // done
- $t += microtime( true );
- $t = round( $t * 1000 );
- if ( $success === false ) {
- $output .= "Error: " .
$job->getLastError() . ", Time: $t ms\n";
- } else {
- $output .= "Success, Time: $t ms\n";
+ if ( !wfShellExecDisabled() && is_executable( $wgPhpCli ) ) {
+ // Start a background process to run some of the jobs.
+ // This will be asynchronous on *nix though not on
Windows.
+ wfProfileIn( __METHOD__ . '-exec' );
+ $retVal = 1;
+ $cmd = wfShellWikiCmd( "$IP/maintenance/runJobs.php",
array( '--maxjobs', $n ) );
+ wfShellExec( "$cmd &", $retVal );
+ wfProfileOut( __METHOD__ . '-exec' );
+ } else {
+ // Fallback to running the jobs here while the user
waits
+ $group = JobQueueGroup::singleton();
+ do {
+ $job = $group->pop( JobQueueGroup::USE_CACHE );
// job from any queue
+ if ( $job ) {
+ $output = $job->toString() . "\n";
+ $t = - microtime( true );
+ wfProfileIn( __METHOD__ . '-' .
get_class( $job ) );
+ $success = $job->run();
+ wfProfileOut( __METHOD__ . '-' .
get_class( $job ) );
+ $group->ack( $job ); // done
+ $t += microtime( true );
+ $t = round( $t * 1000 );
+ if ( $success === false ) {
+ $output .= "Error: " .
$job->getLastError() . ", Time: $t ms\n";
+ } else {
+ $output .= "Success, Time: $t
ms\n";
+ }
+ wfDebugLog( 'jobqueue', $output );
}
- wfDebugLog( 'jobqueue', $output );
- }
- } while ( --$n && $job );
+ } while ( --$n && $job );
+ }
}
}
--
To view, visit https://gerrit.wikimedia.org/r/59797
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6a28152251659ee53eee2604f16d5bf02c85a44f
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Demon <[email protected]>
Gerrit-Reviewer: Tim Starling <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits