require_once __DIR__ . '/../includes/PHPVersionCheck.php';
wfEntryPointCheck( 'cli' );
+use MediaWiki\Shell\Shell;
use Wikimedia\Rdbms\DBReplicationWaitError;
/**
if ( $count < 2 ) {
return false; // sanity
}
- if ( $bt[0]['class'] !== 'Maintenance' || $bt[0]['function'] !== 'shouldExecute' ) {
+ if ( $bt[0]['class'] !== self::class || $bt[0]['function'] !== 'shouldExecute' ) {
return false; // last call should be to this function
}
$includeFuncs = [ 'require_once', 'require', 'include', 'include_once' ];
* @param mixed $channel Unique identifier for the channel. See function outputChanneled.
*/
protected function output( $out, $channel = null ) {
+ // This is sometimes called very early, before Setup.php is included.
+ if ( class_exists( MediaWikiServices::class ) ) {
+ // Try to periodically flush buffered metrics to avoid OOMs
+ $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+ if ( $stats->getDataCount() > 1000 ) {
+ MediaWiki::emitBufferedStatsdData( $stats, $this->getConfig() );
+ }
+ }
+
if ( $this->mQuiet ) {
return;
}
$this->fatalError( $err, intval( $die ) );
}
$this->outputChanneled( false );
- if ( PHP_SAPI == 'cli' ) {
+ if (
+ ( PHP_SAPI == 'cli' || PHP_SAPI == 'phpdbg' ) &&
+ !defined( 'MW_PHPUNIT_TEST' )
+ ) {
fwrite( STDERR, $err . "\n" );
} else {
print $err;
"http://en.wikipedia.org. This is sometimes necessary because " .
"server name detection may fail in command line scripts.", false, true );
$this->addOption( 'profiler', 'Profiler output format (usually "text")', false, true );
+ // This is named --mwdebug, because --debug would conflict in the phpunit.php CLI script.
+ $this->addOption( 'mwdebug', 'Enable built-in MediaWiki development settings', false, true );
# Save generic options to display them separately in help
$this->mGenericParameters = $this->mParams;
$lbFactory->setAgentName(
mb_strlen( $agent ) > 15 ? mb_substr( $agent, 0, 15 ) . '...' : $agent
);
- self::setLBFactoryTriggers( $lbFactory );
+ self::setLBFactoryTriggers( $lbFactory, $this->getConfig() );
}
/**
* @param LBFactory $LBFactory
+ * @param Config $config
* @since 1.28
*/
- public static function setLBFactoryTriggers( LBFactory $LBFactory ) {
+ public static function setLBFactoryTriggers( LBFactory $LBFactory, Config $config ) {
+ $services = MediaWikiServices::getInstance();
+ $stats = $services->getStatsdDataFactory();
// Hook into period lag checks which often happen in long-running scripts
- $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lbFactory = $services->getDBLoadBalancerFactory();
$lbFactory->setWaitForReplicationListener(
__METHOD__,
- function () {
- global $wgCommandLineMode;
+ function () use ( $stats, $config ) {
// Check config in case of JobRunner and unit tests
- if ( $wgCommandLineMode ) {
+ if ( $config->get( 'CommandLineMode' ) ) {
DeferredUpdates::tryOpportunisticExecute( 'run' );
}
+ // Try to periodically flush buffered metrics to avoid OOMs
+ MediaWiki::emitBufferedStatsdData( $stats, $config );
}
);
// Check for other windows to run them. A script may read or do a few writes
// to the master but mostly be writing to something else, like a file store.
$lbFactory->getMainLB()->setTransactionListener(
__METHOD__,
- function ( $trigger ) {
- global $wgCommandLineMode;
+ function ( $trigger ) use ( $stats, $config ) {
// Check config in case of JobRunner and unit tests
- if ( $wgCommandLineMode && $trigger === IDatabase::TRIGGER_COMMIT ) {
+ if ( $config->get( 'CommandLineMode' ) && $trigger === IDatabase::TRIGGER_COMMIT ) {
DeferredUpdates::tryOpportunisticExecute( 'run' );
}
+ // Try to periodically flush buffered metrics to avoid OOMs
+ MediaWiki::emitBufferedStatsdData( $stats, $config );
}
);
}
* Do some sanity checking and basic setup
*/
public function setup() {
- global $IP, $wgCommandLineMode, $wgRequestTime;
+ global $IP, $wgCommandLineMode;
# Abort if called from a web server
- if ( PHP_SAPI !== 'cli' ) {
+ # wfIsCLI() is not available yet
+ if ( PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg' ) {
$this->fatalError( 'This script must be run from the command line' );
}
# But sometimes this doesn't seem to be the case.
ini_set( 'max_execution_time', 0 );
- $wgRequestTime = microtime( true );
-
# Define us as being in MediaWiki
define( 'MEDIAWIKI', true );
// ... append parameters ...
if ( $this->mParams ) {
- $output .= " [--" . implode( array_keys( $this->mParams ), "|--" ) . "]";
+ $output .= " [--" . implode( "|--", array_keys( $this->mParams ) ) . "]";
}
// ... and append arguments.
MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->destroy();
}
+ # Apply debug settings
+ if ( $this->hasOption( 'mwdebug' ) ) {
+ require __DIR__ . '/../includes/DevelopmentSettings.php';
+ }
+
// Per-script profiling; useful for debugging
$this->activateProfiler();
$wgShowSQLErrors = true;
- MediaWiki\suppressWarnings();
+ Wikimedia\suppressWarnings();
set_time_limit( 0 );
- MediaWiki\restoreWarnings();
+ Wikimedia\restoreWarnings();
$this->adjustMemoryLimit();
}
"must exist and be readable in the source directory.\n" .
"Use --conf to specify it." );
}
+ if ( isset( $this->mOptions['server'] ) ) {
+ $_SERVER['SERVER_NAME'] = $this->mOptions['server'];
+ }
$wgCommandLineMode = true;
return $settingsFile;
* This function has the same parameters as wfGetDB()
*
* @param int $db DB index (DB_REPLICA/DB_MASTER)
- * @param array $groups default: empty array
+ * @param string|string[] $groups default: empty array
* @param string|bool $wiki default: current wiki
* @return IMaintainableDatabase
*/
// something that can do the relevant syscalls. There are a few
// options. Linux and Mac OS X both have "stty size" which does the
// job directly.
- $retval = false;
- $size = wfShellExec( 'stty size', $retval );
- if ( $retval !== 0 ) {
+ $result = Shell::command( 'stty', 'size' )
+ ->execute();
+ if ( $result->getExitCode() !== 0 ) {
return $default;
}
- if ( !preg_match( '/^(\d+) (\d+)$/', $size, $m ) ) {
+ if ( !preg_match( '/^(\d+) (\d+)$/', $result->getStdout(), $m ) ) {
return $default;
}
return [ intval( $m[2] ), intval( $m[1] ) ];