diff --git a/resources/sql/autopatches/20140617.daemon.explicit-argv.sql b/resources/sql/autopatches/20140617.daemon.explicit-argv.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20140617.daemon.explicit-argv.sql @@ -0,0 +1,3 @@ +ALTER TABLE {$NAMESPACE}_daemon.daemon_log + ADD COLUMN explicitArgv longtext CHARACTER SET utf8 + COLLATE utf8_bin NOT NULL AFTER argv; diff --git a/src/applications/daemon/event/PhabricatorDaemonEventListener.php b/src/applications/daemon/event/PhabricatorDaemonEventListener.php --- a/src/applications/daemon/event/PhabricatorDaemonEventListener.php +++ b/src/applications/daemon/event/PhabricatorDaemonEventListener.php @@ -37,6 +37,7 @@ ->setPID(getmypid()) ->setStatus(PhabricatorDaemonLog::STATUS_RUNNING) ->setArgv($event->getValue('argv')) + ->setExplicitArgv($event->getValue('explicitArgv')) ->save(); $this->daemons[$id] = $daemon; diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php --- a/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php @@ -7,73 +7,10 @@ $this ->setName('status') ->setSynopsis(pht('Show status of running daemons.')) - ->setArguments( - array( - array( - 'name' => 'all', - 'help' => pht('Show the status of daemons across all hosts.'), - ), - )); + ->setArguments(array()); } public function execute(PhutilArgumentParser $args) { - if ($args->getArg('all')) { - return $this->executeGlobal(); - } else { - return $this->executeLocal(); - } - } - - protected function executeLocal() { - $console = PhutilConsole::getConsole(); - $daemons = $this->loadRunningDaemons(); - - if (!$daemons) { - $console->writeErr( - "%s\n", - pht('There are no running Phabricator daemons.')); - return 1; - } - - $status = 0; - $table = id(new PhutilConsoleTable()) - ->addColumns(array( - 'pid' => array( - 'title' => 'PID', - ), - 'started' => array( - 'title' => 'Started', - ), - 'daemon' => array( - 'title' => 'Daemon', - ), - 'argv' => array( - 'title' => 'Arguments', - ), - )); - - foreach ($daemons as $daemon) { - $name = $daemon->getName(); - if (!$daemon->isRunning()) { - $daemon->updateStatus(PhabricatorDaemonLog::STATUS_DEAD); - $status = 2; - $name = ' '.$name; - } - - $table->addRow(array( - 'pid' => $daemon->getPID(), - 'started' => $daemon->getEpochStarted() - ? date('M j Y, g:i:s A', $daemon->getEpochStarted()) - : null, - 'daemon' => $name, - 'argv' => csprintf('%LR', $daemon->getArgv()), - )); - } - - $table->draw(); - } - - protected function executeGlobal() { $console = PhutilConsole::getConsole(); $daemons = $this->loadAllRunningDaemons(); @@ -109,14 +46,40 @@ )); 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() */), - )); + if ($daemon instanceof PhabricatorDaemonLog) { + $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', $daemon->getExplicitArgv()), + )); + } else if ($daemon instanceof PhabricatorDaemonReference) { + $name = $daemon->getName(); + if (!$daemon->isRunning()) { + $daemon->updateStatus(PhabricatorDaemonLog::STATUS_DEAD); + $status = 2; + $name = ' '.$name; + } + + $daemon_log = $daemon->getDaemonLog(); + $id = null; + if ($daemon_log) { + $id = $daemon_log->getID(); + } + + $table->addRow(array( + 'id' => $id, + 'host' => 'localhost', + 'pid' => $daemon->getPID(), + 'started' => $daemon->getEpochStarted() + ? date('M j Y, g:i:s A', $daemon->getEpochStarted()) + : null, + 'daemon' => $name, + 'argv' => csprintf('%LR', $daemon->getArgv()), + )); + } } $table->draw(); diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php --- a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php @@ -36,35 +36,38 @@ } protected final function loadRunningDaemons() { - $results = array(); + $daemons = array(); $pid_dir = $this->getPIDDirectory(); $pid_files = Filesystem::listDirectory($pid_dir); - if (!$pid_files) { - return $results; - } foreach ($pid_files as $pid_file) { - $pid_data = Filesystem::readFile($pid_dir.'/'.$pid_file); - $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 = PhabricatorDaemonReference::newFromDictionary($dict); - $ref->setPIDFile($pid_dir.'/'.$pid_file); - $results[] = $ref; + $daemons[] = PhabricatorDaemonReference::newFromFile( + $pid_dir.'/'.$pid_file); } - return $results; + return $daemons; } protected final function loadAllRunningDaemons() { - return id(new PhabricatorDaemonLogQuery()) + $local_daemons = $this->loadRunningDaemons(); + + $local_ids = array(); + foreach ($local_daemons as $daemon) { + $daemon_log = $daemon->getDaemonLog(); + + if ($daemon_log) { + $local_ids[] = $daemon_log->getID(); + } + } + + $remote_daemons = id(new PhabricatorDaemonLogQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withoutIDs($local_ids) ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) ->execute(); + + return array_merge($local_daemons, $remote_daemons); } private function findDaemonClass($substring) { @@ -280,7 +283,6 @@ } $console->writeErr(pht('Done.')."\n"); - return 0; } diff --git a/src/applications/daemon/storage/PhabricatorDaemonLog.php b/src/applications/daemon/storage/PhabricatorDaemonLog.php --- a/src/applications/daemon/storage/PhabricatorDaemonLog.php +++ b/src/applications/daemon/storage/PhabricatorDaemonLog.php @@ -13,12 +13,14 @@ protected $host; protected $pid; protected $argv; + protected $explicitArgv; protected $status; public function getConfiguration() { return array( self::CONFIG_SERIALIZATION => array( 'argv' => self::SERIALIZATION_JSON, + 'explicitArgv' => self::SERIALIZATION_JSON, ), ) + parent::getConfiguration(); } diff --git a/src/infrastructure/daemon/control/PhabricatorDaemonReference.php b/src/infrastructure/daemon/control/PhabricatorDaemonReference.php --- a/src/infrastructure/daemon/control/PhabricatorDaemonReference.php +++ b/src/infrastructure/daemon/control/PhabricatorDaemonReference.php @@ -10,6 +10,14 @@ private $daemonLog; + public static function newFromFile($path) { + $pid_data = Filesystem::readFile($path); + $dict = phutil_json_decode($pid_data); + $ref = self::newFromDictionary($dict); + $ref->pidFile = $path; + return $ref; + } + public static function newFromDictionary(array $dict) { $ref = new PhabricatorDaemonReference(); @@ -18,6 +26,12 @@ $ref->pid = idx($dict, 'pid'); $ref->start = idx($dict, 'start'); + $ref->daemonLog = id(new PhabricatorDaemonLog())->loadOneWhere( + 'daemon = %s AND pid = %d AND dateCreated = %d', + $ref->name, + $ref->pid, + $ref->start); + return $ref; } @@ -66,15 +80,14 @@ return $this->start; } - public function setPIDFile($pid_file) { - $this->pidFile = $pid_file; - return $this; - } - public function getPIDFile() { return $this->pidFile; } + public function getDaemonLog() { + return $this->daemonLog; + } + public function isRunning() { return self::isProcessRunning($this->getPID()); }