Page MenuHomePhabricator

D11853.id28608.diff
No OneTemporary

D11853.id28608.diff

diff --git a/scripts/daemon/exec/exec_daemon.php b/scripts/daemon/exec/exec_daemon.php
--- a/scripts/daemon/exec/exec_daemon.php
+++ b/scripts/daemon/exec/exec_daemon.php
@@ -28,41 +28,48 @@
'help' => 'Enable debug memory tracing.',
),
array(
- 'name' => 'log',
- 'param' => 'file',
- 'help' => 'Send output to __file__.',
- ),
- array(
- 'name' => 'load-phutil-library',
- 'param' => 'library',
- 'repeat' => true,
- 'help' => 'Load __library__.',
- ),
- array(
'name' => 'verbose',
'help' => 'Enable verbose activity logging.',
),
array(
- 'name' => 'argv',
+ 'name' => 'label',
+ 'short' => 'l',
+ 'param' => 'label',
+ 'help' => pht(
+ 'Optional process label. Makes "ps" nicer, no behavioral effects.'),
+ ),
+ array(
+ 'name' => 'daemon',
'wildcard' => true,
),
));
$trace_memory = $args->getArg('trace-memory');
-$trace_mode = $args->getArg('trace') || $trace_memory;
-$verbose = $args->getArg('verbose');
+$trace_mode = $args->getArg('trace') || $trace_memory;
+$verbose = $args->getArg('verbose');
+
+if (function_exists('posix_isatty') && posix_isatty(STDIN)) {
+ fprintf(STDERR, pht('Reading daemon configuration from stdin...')."\n");
+}
+$config = @file_get_contents('php://stdin');
+$config = id(new PhutilJSONParser())->parse($config);
+
+PhutilTypeSpec::checkMap(
+ $config,
+ array(
+ 'log' => 'optional string|null',
+ 'argv' => 'optional list<wild>',
+ 'load' => 'optional list<string>',
+ ));
+
+$log = idx($config, 'log');
-$log = $args->getArg('log');
if ($log) {
ini_set('error_log', $log);
- $echo_to_stderr = true;
-} else {
- $echo_to_stderr = false;
+ PhutilErrorHandler::setErrorListener(array('PhutilDaemon', 'errorListener'));
}
-$load = $args->getArg('load-phutil-library');
-$argv = $args->getArg('argv');
-
+$load = idx($config, 'load', array());
foreach ($load as $library) {
$library = Filesystem::resolvePath($library);
phutil_load_library($library);
@@ -70,40 +77,35 @@
PhutilErrorHandler::initialize();
-function phutil_daemon_error_listener($event, $value, array $metadata) {
- $console = PhutilConsole::getConsole();
- $message = idx($metadata, 'default_message');
-
- if ($message) {
- $console->writeErr("%s\n", $message);
- }
- if (idx($metadata, 'trace')) {
- $trace = PhutilErrorHandler::formatStacktrace($metadata['trace']);
- $console->writeErr("%s\n", $trace);
- }
-}
-
-if ($echo_to_stderr) {
- // If the caller has used `--log` to redirect the error log to a file, PHP
- // won't output it to stderr so the overseer can't capture it and won't be
- // able to send it to the web console. Install a listener which just echoes
- // errors to stderr, so we always get all the messages in the log and over
- // stdio, so they'll show up in the web console.
- PhutilErrorHandler::setErrorListener('phutil_daemon_error_listener');
-}
-
-$daemon = array_shift($argv);
+$daemon = $args->getArg('daemon');
if (!$daemon) {
- $args->printHelpAndExit();
+ throw new PhutilArgumentUsageException(
+ pht('Specify which class of daemon to start.'));
+} else if (count($daemon) > 1) {
+ throw new PhutilArgumentUsageException(
+ pht('Specify exactly one daemon to start.'));
+} else {
+ $daemon = head($daemon);
+ if (!class_exists($daemon)) {
+ throw new PhutilArgumentUsageException(
+ pht('No class "%s" exists in any known library.', $daemon));
+ } else if (!is_subclass_of($daemon, 'PhutilDaemon')) {
+ throw new PhutilArgumentUsageException(
+ pht('Class "%s" is not a subclass of "%s".', $daemon, 'PhutilDaemon'));
+ }
}
+$argv = idx($config, 'argv', array());
$daemon = newv($daemon, array($argv));
+
if ($trace_mode) {
$daemon->setTraceMode();
}
+
if ($trace_memory) {
$daemon->setTraceMemory();
}
+
if ($verbose) {
$daemon->setVerbose(true);
}
diff --git a/src/daemon/PhutilDaemon.php b/src/daemon/PhutilDaemon.php
--- a/src/daemon/PhutilDaemon.php
+++ b/src/daemon/PhutilDaemon.php
@@ -187,5 +187,22 @@
$this->beginStdoutCapture();
}
+ public static function errorListener($event, $value, array $metadata) {
+ // If the caller has redirected the error log to a file, PHP won't output
+ // messages to stderr, so the overseer can't capture them. Install a
+ // listener which just echoes errors to stderr, so the overseer is always
+ // aware of errors.
+
+ $console = PhutilConsole::getConsole();
+ $message = idx($metadata, 'default_message');
+
+ if ($message) {
+ $console->writeErr("%s\n", $message);
+ }
+ if (idx($metadata, 'trace')) {
+ $trace = PhutilErrorHandler::formatStacktrace($metadata['trace']);
+ $console->writeErr("%s\n", $trace);
+ }
+ }
}
diff --git a/src/daemon/PhutilDaemonHandle.php b/src/daemon/PhutilDaemonHandle.php
--- a/src/daemon/PhutilDaemonHandle.php
+++ b/src/daemon/PhutilDaemonHandle.php
@@ -26,12 +26,12 @@
PhutilDaemonOverseer $overseer,
$daemon_class,
array $argv,
- array $more) {
+ array $config) {
$this->overseer = $overseer;
$this->daemonClass = $daemon_class;
$this->argv = $argv;
- $this->more = $more;
+ $this->config = $config;
$this->restartAt = time();
$this->daemonID = $this->generateDaemonID();
@@ -39,7 +39,7 @@
self::EVENT_DID_LAUNCH,
array(
'argv' => $this->argv,
- 'explicitArgv' => $this->more,
+ 'explicitArgv' => idx($this->config, 'argv'),
));
}
@@ -185,7 +185,7 @@
private function newExecFuture() {
$class = $this->daemonClass;
- $argv = array_merge($this->argv, array('--'), $this->more);
+ $argv = $this->argv;
$buffer_size = $this->getCaptureBufferSize();
// NOTE: PHP implements proc_open() by running 'sh -c'. On most systems this
@@ -204,7 +204,8 @@
return id(new ExecFuture('exec ./exec_daemon.php %s %Ls', $class, $argv))
->setCWD($this->getDaemonCWD())
->setStdoutSizeLimit($buffer_size)
- ->setStderrSizeLimit($buffer_size);
+ ->setStderrSizeLimit($buffer_size)
+ ->write(json_encode($this->config));
}
/**
diff --git a/src/daemon/PhutilDaemonOverseer.php b/src/daemon/PhutilDaemonOverseer.php
--- a/src/daemon/PhutilDaemonOverseer.php
+++ b/src/daemon/PhutilDaemonOverseer.php
@@ -17,6 +17,8 @@
private $traceMemory;
private $daemonize;
private $phddir;
+ private $log;
+ private $libraries = array();
private $verbose;
private $err = 0;
@@ -57,6 +59,13 @@
'help' => 'Enable verbose activity logging.',
),
array(
+ 'name' => 'label',
+ 'short' => 'l',
+ 'param' => 'label',
+ 'help' => pht(
+ 'Optional process label. Makes "ps" nicer, no behavioral effects.'),
+ ),
+ array(
'name' => 'load-phutil-library',
'param' => 'library',
'repeat' => true,
@@ -85,13 +94,13 @@
if ($args->getArg('load-phutil-library')) {
foreach ($args->getArg('load-phutil-library') as $library) {
- $argv[] = '--load-phutil-library='.$library;
+ $this->libraries[] = $library;
}
}
$log = $args->getArg('log');
if ($log) {
- $argv[] = '--log='.$log;
+ $this->log = $log;
}
$verbose = $args->getArg('verbose');
@@ -100,10 +109,16 @@
$argv[] = '--verbose';
}
- $this->daemonize = $args->getArg('daemonize');
- $this->phddir = $args->getArg('phd');
- $this->argv = $argv;
- $this->moreArgs = coalesce($more, array());
+ $label = $args->getArg('label');
+ if ($label) {
+ $argv[] = '-l';
+ $argv[] = $label;
+ }
+
+ $this->daemonize = $args->getArg('daemonize');
+ $this->phddir = $args->getArg('phd');
+ $this->argv = $argv;
+ $this->moreArgs = coalesce($more, array());
if (self::$instance) {
throw new Exception(
@@ -174,7 +189,11 @@
$this,
$this->daemon,
$this->argv,
- $this->moreArgs);
+ array(
+ 'log' => $this->log,
+ 'argv' => $this->moreArgs,
+ 'load' => $this->libraries,
+ ));
$daemon->setSilent((!$this->traceMode && !$this->verbose));
$daemon->setTraceMemory($this->traceMemory);

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 18, 12:09 AM (4 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7709105
Default Alt Text
D11853.id28608.diff (8 KB)

Event Timeline