1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

Add a "phd debug" command

Summary:
Make it easier to find obvious problems in daemons by letting them run
undaemonized in the console without requiring the user to know the magical
incantations for loading libraries, etc.

Test Plan:
Ran "phd debug nice", simulated some failures (e.g., bringing down Phabricator,
daemon fatal) and got useful error messages.

Reviewed By: jungejason
Reviewers: toulouse, jungejason, tuomaspelkonen, aran
CC: aran, jungejason
Differential Revision: 448
This commit is contained in:
epriestley 2011-06-13 10:01:06 -07:00
parent 33e6229969
commit cb0cbc50ad
3 changed files with 53 additions and 18 deletions

View file

@ -105,6 +105,9 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
break; break;
case 'launch': case 'launch':
case 'debug':
$is_debug = ($argv[1] == 'debug');
$daemon = idx($argv, 2); $daemon = idx($argv, 2);
if (!$daemon) { if (!$daemon) {
throw new Exception("Daemon name required!"); throw new Exception("Daemon name required!");
@ -113,16 +116,18 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
$pass_argv = array_slice($argv, 3); $pass_argv = array_slice($argv, 3);
$n = 1; $n = 1;
if (is_numeric($daemon)) { if (!$is_debug) {
$n = $daemon; if (is_numeric($daemon)) {
if ($n < 1) { $n = $daemon;
throw new Exception("Count must be at least 1!"); if ($n < 1) {
throw new Exception("Count must be at least 1!");
}
$daemon = idx($argv, 3);
if (!$daemon) {
throw new Exception("Daemon name required!");
}
$pass_argv = array_slice($argv, 4);
} }
$daemon = idx($argv, 3);
if (!$daemon) {
throw new Exception("Daemon name required!");
}
$pass_argv = array_slice($argv, 4);
} }
$loader = new PhutilSymbolLoader(); $loader = new PhutilSymbolLoader();
@ -154,11 +159,17 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
$daemon = reset($match); $daemon = reset($match);
} }
echo "Launching {$n} x {$daemon}"; if ($is_debug) {
echo "Launching {$daemon} in debug mode (nondaemonized)...\n";
} else {
echo "Launching {$n} x {$daemon}";
}
for ($ii = 0; $ii < $n; $ii++) { for ($ii = 0; $ii < $n; $ii++) {
$control->launchDaemon($daemon, $pass_argv); $control->launchDaemon($daemon, $pass_argv, $is_debug);
echo "."; if (!$is_debug) {
echo ".";
}
} }
echo "\n"; echo "\n";

View file

@ -34,6 +34,7 @@ a list of commands, run ##phd help##:
Generally, you will use: Generally, you will use:
- **phd launch** to launch daemons; - **phd launch** to launch daemons;
- **phd debug** to debug problems with daemons;
- **phd status** to get a list of running daemons; and - **phd status** to get a list of running daemons; and
- **phd stop** to stop all daemons. - **phd stop** to stop all daemons.
@ -54,6 +55,10 @@ allows you to view log information for them. If you have issues with daemons,
you may be able to find error information that will help you resolve the problem you may be able to find error information that will help you resolve the problem
in the console. in the console.
NOTE: The easiest way to figure out what's wrong with a daemon is usually to use
**phd debug** to launch it instead of **phd launch**. This will run it without
daemonizing it, so you can see output in your console.
= Available Daemons = = Available Daemons =
You can get a list of launchable daemons with **phd list**: You can get a list of launchable daemons with **phd list**:

View file

@ -128,7 +128,10 @@ final class PhabricatorDaemonControl {
**COMMAND REFERENCE** **COMMAND REFERENCE**
**launch** [__n__] __daemon__ [argv ...] **launch** [__n__] __daemon__ [argv ...]
**debug** __daemon__ [argv ...]
Start a daemon (or n copies of a daemon). Start a daemon (or n copies of a daemon).
With **debug**, do not daemonize. Use this if you're having trouble
getting daemons working.
**list** **list**
List available daemons. List available daemons.
@ -160,7 +163,7 @@ EOHELP
return 1; return 1;
} }
public function launchDaemon($daemon, array $argv) { public function launchDaemon($daemon, array $argv, $debug) {
$symbols = $this->loadAvailableDaemonClasses(); $symbols = $this->loadAvailableDaemonClasses();
$symbols = ipull($symbols, 'name', 'name'); $symbols = ipull($symbols, 'name', 'name');
if (empty($symbols[$daemon])) { if (empty($symbols[$daemon])) {
@ -195,24 +198,40 @@ EOHELP
phutil_get_library_root($library)); phutil_get_library_root($library));
} }
$future = new ExecFuture( $command = csprintf(
"./launch_daemon.php ". "./launch_daemon.php ".
"%s ". "%s ".
"--load-phutil-library=%s ". "--load-phutil-library=%s ".
implode(' ', $extra_libraries)." ". implode(' ', $extra_libraries)." ".
"--conduit-uri=%s ". "--conduit-uri=%s ".
"--daemonize ".
"--phd=%s ". "--phd=%s ".
($debug ? '--trace ' : '--daemonize ').
implode(' ', $argv), implode(' ', $argv),
$daemon, $daemon,
phutil_get_library_root('phabricator'), phutil_get_library_root('phabricator'),
PhabricatorEnv::getURI('/api/'), PhabricatorEnv::getURI('/api/'),
$pid_dir); $pid_dir);
// Play games to keep 'ps' looking reasonable. if ($debug) {
$future->setCWD($launch_daemon); // Don't terminate when the user sends ^C; it will be sent to the
// subprocess which will terminate normally.
pcntl_signal(
SIGINT,
array('PhabricatorDaemonControl', 'ignoreSignal'));
$future->resolvex(); echo "\n libphutil/scripts/daemon/ \$ {$command}\n\n";
phutil_passthru('(cd %s && exec %C)', $launch_daemon, $command);
} else {
$future = new ExecFuture('exec %C', $command);
// Play games to keep 'ps' looking reasonable.
$future->setCWD($launch_daemon);
$future->resolvex();
}
}
public static function ignoreSignal($signo) {
return;
} }
protected function getControlDirectory($dir) { protected function getControlDirectory($dir) {