Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15398460
D11853.id28608.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D11853.id28608.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D11853: Pass most daemon configuration over stdin
Attached
Detach File
Event Timeline
Log In to Comment