mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +01:00
Query daemons across all hosts with ./bin/phd status --all
.
Summary: Ref T4209. Currently, `./bin/phd status` prints a table showing the daemons that are executing on the current host. It would be useful to be able to conventiently query the daemons running across all hosts. This would also (theoretically) make it possible to conditionally start daemons on a host depending upon the current state and on the daemons running on other hosts. Test Plan: ``` > ./bin/phd status --all ID Host PID Started Daemon Arguments 18 phabricator 6969 Jun 12 2014, 4:44:22 PM PhabricatorTaskmasterDaemon 17 phabricator 6961 Jun 12 2014, 4:44:19 PM PhabricatorTaskmasterDaemon 16 phabricator 6955 Jun 12 2014, 4:44:15 PM PhabricatorTaskmasterDaemon 15 phabricator 6950 Jun 12 2014, 4:44:14 PM PhabricatorTaskmasterDaemon 14 phabricator 6936 Jun 12 2014, 4:44:13 PM PhabricatorGarbageCollectorDaemon 13 phabricator 6931 Jun 12 2014, 4:44:12 PM PhabricatorRepositoryPullLocalDaemon ``` Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T4209 Differential Revision: https://secure.phabricator.com/D9497
This commit is contained in:
parent
78635a15c1
commit
0ccebbe4b1
3 changed files with 113 additions and 39 deletions
|
@ -22,12 +22,22 @@ final class PhabricatorDaemonManagementStatusWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
$status = 0;
|
$status = 0;
|
||||||
printf(
|
$table = id(new PhutilConsoleTable())
|
||||||
"%-5s\t%-24s\t%-50s%s\n",
|
->addColumns(array(
|
||||||
'PID',
|
'pid' => array(
|
||||||
'Started',
|
'title' => 'PID',
|
||||||
'Daemon',
|
),
|
||||||
'Arguments');
|
'started' => array(
|
||||||
|
'title' => 'Started',
|
||||||
|
),
|
||||||
|
'daemon' => array(
|
||||||
|
'title' => 'Daemon',
|
||||||
|
),
|
||||||
|
'argv' => array(
|
||||||
|
'title' => 'Arguments',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
foreach ($daemons as $daemon) {
|
foreach ($daemons as $daemon) {
|
||||||
$name = $daemon->getName();
|
$name = $daemon->getName();
|
||||||
if (!$daemon->isRunning()) {
|
if (!$daemon->isRunning()) {
|
||||||
|
@ -35,18 +45,67 @@ final class PhabricatorDaemonManagementStatusWorkflow
|
||||||
$status = 2;
|
$status = 2;
|
||||||
$name = '<DEAD> '.$name;
|
$name = '<DEAD> '.$name;
|
||||||
}
|
}
|
||||||
printf(
|
|
||||||
"%5s\t%-24s\t%-50s%s\n",
|
$table->addRow(array(
|
||||||
$daemon->getPID(),
|
'pid' => $daemon->getPID(),
|
||||||
$daemon->getEpochStarted()
|
'started' => $daemon->getEpochStarted()
|
||||||
? date('M j Y, g:i:s A', $daemon->getEpochStarted())
|
? date('M j Y, g:i:s A', $daemon->getEpochStarted())
|
||||||
: null,
|
: null,
|
||||||
$name,
|
'daemon' => $name,
|
||||||
csprintf('%LR', $daemon->getArgv()));
|
'argv' => csprintf('%LR', $daemon->getArgv()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $status;
|
$table->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function executeGlobal() {
|
||||||
|
$console = PhutilConsole::getConsole();
|
||||||
|
$daemons = $this->loadAllRunningDaemons();
|
||||||
|
|
||||||
|
if (!$daemons) {
|
||||||
|
$console->writeErr(
|
||||||
|
"%s\n",
|
||||||
|
pht('There are no running Phabricator daemons.'));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = 0;
|
||||||
|
|
||||||
|
$table = id(new PhutilConsoleTable())
|
||||||
|
->addColumns(array(
|
||||||
|
'id' => array(
|
||||||
|
'title' => 'ID',
|
||||||
|
),
|
||||||
|
'host' => array(
|
||||||
|
'title' => 'Host',
|
||||||
|
),
|
||||||
|
'pid' => array(
|
||||||
|
'title' => 'PID',
|
||||||
|
),
|
||||||
|
'started' => array(
|
||||||
|
'title' => 'Started',
|
||||||
|
),
|
||||||
|
'daemon' => array(
|
||||||
|
'title' => 'Daemon',
|
||||||
|
),
|
||||||
|
'argv' => array(
|
||||||
|
'title' => 'Arguments',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
foreach ($daemons as $daemon) {
|
||||||
|
$table->addRow(array(
|
||||||
|
'id' => $daemon->getID(),
|
||||||
|
'host' => $daemon->getHost(),
|
||||||
|
'pid' => $daemon->getPID(),
|
||||||
|
'started' => date('M j Y, g:i:s A', $daemon->getDateCreated()),
|
||||||
|
'daemon' => $daemon->getDaemon(),
|
||||||
|
'argv' => csprintf('%LR', array() /* $daemon->getArgv() */),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->draw();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
abstract class PhabricatorDaemonManagementWorkflow
|
abstract class PhabricatorDaemonManagementWorkflow
|
||||||
extends PhabricatorManagementWorkflow {
|
extends PhabricatorManagementWorkflow {
|
||||||
|
|
||||||
protected function loadAvailableDaemonClasses() {
|
protected final function loadAvailableDaemonClasses() {
|
||||||
$loader = new PhutilSymbolLoader();
|
$loader = new PhutilSymbolLoader();
|
||||||
return $loader
|
return $loader
|
||||||
->setAncestorClass('PhutilDaemon')
|
->setAncestorClass('PhutilDaemon')
|
||||||
|
@ -11,12 +11,12 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
->selectSymbolsWithoutLoading();
|
->selectSymbolsWithoutLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPIDDirectory() {
|
protected final function getPIDDirectory() {
|
||||||
$path = PhabricatorEnv::getEnvConfig('phd.pid-directory');
|
$path = PhabricatorEnv::getEnvConfig('phd.pid-directory');
|
||||||
return $this->getControlDirectory($path);
|
return $this->getControlDirectory($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLogDirectory() {
|
protected final function getLogDirectory() {
|
||||||
$path = PhabricatorEnv::getEnvConfig('phd.log-directory');
|
$path = PhabricatorEnv::getEnvConfig('phd.log-directory');
|
||||||
return $this->getControlDirectory($path);
|
return $this->getControlDirectory($path);
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,9 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loadRunningDaemons() {
|
protected final function loadRunningDaemons() {
|
||||||
$results = array();
|
$results = array();
|
||||||
|
$ids = array();
|
||||||
|
|
||||||
$pid_dir = $this->getPIDDirectory();
|
$pid_dir = $this->getPIDDirectory();
|
||||||
$pid_files = Filesystem::listDirectory($pid_dir);
|
$pid_files = Filesystem::listDirectory($pid_dir);
|
||||||
|
@ -45,19 +46,17 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($pid_files as $pid_file) {
|
foreach ($pid_files as $pid_file) {
|
||||||
$pid_data = Filesystem::readFile($pid_dir.'/'.$pid_file);
|
$results[] = PhabricatorDaemonReference::newFromDictionary(
|
||||||
$dict = json_decode($pid_data, true);
|
$pid_dir.'/'.$pid_file);
|
||||||
if (!is_array($dict)) {
|
$ids[] = $ref->getDaemonLog()->getID();
|
||||||
// Just return a hanging reference, since control code needs to be
|
|
||||||
// robust against unusual system states.
|
|
||||||
$dict = array();
|
|
||||||
}
|
|
||||||
$ref = PhabricatorDaemonReference::newFromDictionary($dict);
|
|
||||||
$ref->setPIDFile($pid_dir.'/'.$pid_file);
|
|
||||||
$results[] = $ref;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
$other = id(new PhabricatorDaemonLogQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function findDaemonClass($substring) {
|
private function findDaemonClass($substring) {
|
||||||
|
@ -93,8 +92,7 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
return head($match);
|
return head($match);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final function launchDaemon($class, array $argv, $debug) {
|
||||||
protected function launchDaemon($class, array $argv, $debug) {
|
|
||||||
$daemon = $this->findDaemonClass($class);
|
$daemon = $this->findDaemonClass($class);
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
|
|
||||||
|
@ -212,7 +210,7 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function willLaunchDaemons() {
|
protected final function willLaunchDaemons() {
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
$console->writeErr(pht('Preparing to launch daemons.')."\n");
|
$console->writeErr(pht('Preparing to launch daemons.')."\n");
|
||||||
|
|
||||||
|
@ -224,7 +222,7 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
/* -( Commands )----------------------------------------------------------- */
|
/* -( Commands )----------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
protected function executeStartCommand($keep_leases = false) {
|
protected final function executeStartCommand($keep_leases = false) {
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
|
|
||||||
$running = $this->loadRunningDaemons();
|
$running = $this->loadRunningDaemons();
|
||||||
|
@ -278,8 +276,7 @@ abstract class PhabricatorDaemonManagementWorkflow
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final function executeStopCommand(array $pids) {
|
||||||
protected function executeStopCommand(array $pids) {
|
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
|
|
||||||
$daemons = $this->loadRunningDaemons();
|
$daemons = $this->loadRunningDaemons();
|
||||||
|
|
|
@ -10,6 +10,19 @@ final class PhabricatorDaemonReference {
|
||||||
|
|
||||||
private $daemonLog;
|
private $daemonLog;
|
||||||
|
|
||||||
|
public static function newFromFile($path) {
|
||||||
|
$pid_data = Filesystem::readFile($path);
|
||||||
|
$dict = json_decode($pid_data, true);
|
||||||
|
if (!is_array($dict)) {
|
||||||
|
// Just return a hanging reference, since control code needs to be
|
||||||
|
// robust against unusual system states.
|
||||||
|
$dict = array();
|
||||||
|
}
|
||||||
|
$ref = self::newFromDictionary($dict);
|
||||||
|
$ref->pidFile = $path;
|
||||||
|
return $ref;
|
||||||
|
}
|
||||||
|
|
||||||
public static function newFromDictionary(array $dict) {
|
public static function newFromDictionary(array $dict) {
|
||||||
$ref = new PhabricatorDaemonReference();
|
$ref = new PhabricatorDaemonReference();
|
||||||
|
|
||||||
|
@ -18,6 +31,12 @@ final class PhabricatorDaemonReference {
|
||||||
$ref->pid = idx($dict, 'pid');
|
$ref->pid = idx($dict, 'pid');
|
||||||
$ref->start = idx($dict, 'start');
|
$ref->start = idx($dict, 'start');
|
||||||
|
|
||||||
|
$this->daemonLog = id(new PhabricatorDaemonLog())->loadOneWhere(
|
||||||
|
'daemon = %s AND pid = %d AND dateCreated = %d',
|
||||||
|
$this->name,
|
||||||
|
$this->pid,
|
||||||
|
$this->start);
|
||||||
|
|
||||||
return $ref;
|
return $ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,15 +85,14 @@ final class PhabricatorDaemonReference {
|
||||||
return $this->start;
|
return $this->start;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPIDFile($pid_file) {
|
|
||||||
$this->pidFile = $pid_file;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPIDFile() {
|
public function getPIDFile() {
|
||||||
return $this->pidFile;
|
return $this->pidFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDaemonLog() {
|
||||||
|
return $this->daemonLog;
|
||||||
|
}
|
||||||
|
|
||||||
public function isRunning() {
|
public function isRunning() {
|
||||||
return self::isProcessRunning($this->getPID());
|
return self::isProcessRunning($this->getPID());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue