@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Unify the local and global view for `./bin/phd status`.

Summary:
Ref T4209. Unifies the local (`./bin/phd status`) and global (`./bin/phd status --all`) view into a single table. This generally makes it easy to administer daemons running across multiple hosts.

Depends on D9606.

Test Plan:
```
> sudo ./bin/phd status
ID Host PID Started Daemon Arguments
38 localhost 2282 Jun 18 2014, 7:52:56 AM PhabricatorRepositoryPullLocalDaemon
39 localhost 2289 Jun 18 2014, 7:52:57 AM PhabricatorGarbageCollectorDaemon
40 localhost 2294 Jun 18 2014, 7:52:57 AM PhabricatorTaskmasterDaemon
41 localhost 2314 Jun 18 2014, 7:52:58 AM PhabricatorTaskmasterDaemon
42 localhost 2319 Jun 18 2014, 7:52:59 AM PhabricatorTaskmasterDaemon
43 localhost 2328 Jun 18 2014, 7:53:00 AM PhabricatorTaskmasterDaemon
44 localhost 2354 Jun 18 2014, 7:53:08 AM PhabricatorRepositoryPullLocalDaemon X --not Y
```

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: epriestley, Korvin

Maniphest Tasks: T4209

Differential Revision: https://secure.phabricator.com/D9607

+78 -94
+3
resources/sql/autopatches/20140617.daemon.explicit-argv.sql
··· 1 + ALTER TABLE {$NAMESPACE}_daemon.daemon_log 2 + ADD COLUMN explicitArgv longtext CHARACTER SET utf8 3 + COLLATE utf8_bin NOT NULL AFTER argv;
+1
src/applications/daemon/event/PhabricatorDaemonEventListener.php
··· 37 37 ->setPID(getmypid()) 38 38 ->setStatus(PhabricatorDaemonLog::STATUS_RUNNING) 39 39 ->setArgv($event->getValue('argv')) 40 + ->setExplicitArgv($event->getValue('explicitArgv')) 40 41 ->save(); 41 42 42 43 $this->daemons[$id] = $daemon;
+35 -72
src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php
··· 7 7 $this 8 8 ->setName('status') 9 9 ->setSynopsis(pht('Show status of running daemons.')) 10 - ->setArguments( 11 - array( 12 - array( 13 - 'name' => 'all', 14 - 'help' => pht('Show the status of daemons across all hosts.'), 15 - ), 16 - )); 10 + ->setArguments(array()); 17 11 } 18 12 19 13 public function execute(PhutilArgumentParser $args) { 20 - if ($args->getArg('all')) { 21 - return $this->executeGlobal(); 22 - } else { 23 - return $this->executeLocal(); 24 - } 25 - } 26 - 27 - protected function executeLocal() { 28 - $console = PhutilConsole::getConsole(); 29 - $daemons = $this->loadRunningDaemons(); 30 - 31 - if (!$daemons) { 32 - $console->writeErr( 33 - "%s\n", 34 - pht('There are no running Phabricator daemons.')); 35 - return 1; 36 - } 37 - 38 - $status = 0; 39 - $table = id(new PhutilConsoleTable()) 40 - ->addColumns(array( 41 - 'pid' => array( 42 - 'title' => 'PID', 43 - ), 44 - 'started' => array( 45 - 'title' => 'Started', 46 - ), 47 - 'daemon' => array( 48 - 'title' => 'Daemon', 49 - ), 50 - 'argv' => array( 51 - 'title' => 'Arguments', 52 - ), 53 - )); 54 - 55 - foreach ($daemons as $daemon) { 56 - $name = $daemon->getName(); 57 - if (!$daemon->isRunning()) { 58 - $daemon->updateStatus(PhabricatorDaemonLog::STATUS_DEAD); 59 - $status = 2; 60 - $name = '<DEAD> '.$name; 61 - } 62 - 63 - $table->addRow(array( 64 - 'pid' => $daemon->getPID(), 65 - 'started' => $daemon->getEpochStarted() 66 - ? date('M j Y, g:i:s A', $daemon->getEpochStarted()) 67 - : null, 68 - 'daemon' => $name, 69 - 'argv' => csprintf('%LR', $daemon->getArgv()), 70 - )); 71 - } 72 - 73 - $table->draw(); 74 - } 75 - 76 - protected function executeGlobal() { 77 14 $console = PhutilConsole::getConsole(); 78 15 $daemons = $this->loadAllRunningDaemons(); 79 16 ··· 109 46 )); 110 47 111 48 foreach ($daemons as $daemon) { 112 - $table->addRow(array( 113 - 'id' => $daemon->getID(), 114 - 'host' => $daemon->getHost(), 115 - 'pid' => $daemon->getPID(), 116 - 'started' => date('M j Y, g:i:s A', $daemon->getDateCreated()), 117 - 'daemon' => $daemon->getDaemon(), 118 - 'argv' => csprintf('%LR', array() /* $daemon->getArgv() */), 119 - )); 49 + if ($daemon instanceof PhabricatorDaemonLog) { 50 + $table->addRow(array( 51 + 'id' => $daemon->getID(), 52 + 'host' => $daemon->getHost(), 53 + 'pid' => $daemon->getPID(), 54 + 'started' => date('M j Y, g:i:s A', $daemon->getDateCreated()), 55 + 'daemon' => $daemon->getDaemon(), 56 + 'argv' => csprintf('%LR', $daemon->getExplicitArgv()), 57 + )); 58 + } else if ($daemon instanceof PhabricatorDaemonReference) { 59 + $name = $daemon->getName(); 60 + if (!$daemon->isRunning()) { 61 + $daemon->updateStatus(PhabricatorDaemonLog::STATUS_DEAD); 62 + $status = 2; 63 + $name = '<DEAD> '.$name; 64 + } 65 + 66 + $daemon_log = $daemon->getDaemonLog(); 67 + $id = null; 68 + if ($daemon_log) { 69 + $id = $daemon_log->getID(); 70 + } 71 + 72 + $table->addRow(array( 73 + 'id' => $id, 74 + 'host' => 'localhost', 75 + 'pid' => $daemon->getPID(), 76 + 'started' => $daemon->getEpochStarted() 77 + ? date('M j Y, g:i:s A', $daemon->getEpochStarted()) 78 + : null, 79 + 'daemon' => $name, 80 + 'argv' => csprintf('%LR', $daemon->getArgv()), 81 + )); 82 + } 120 83 } 121 84 122 85 $table->draw();
+19 -17
src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php
··· 36 36 } 37 37 38 38 protected final function loadRunningDaemons() { 39 - $results = array(); 39 + $daemons = array(); 40 40 41 41 $pid_dir = $this->getPIDDirectory(); 42 42 $pid_files = Filesystem::listDirectory($pid_dir); 43 - if (!$pid_files) { 44 - return $results; 45 - } 46 43 47 44 foreach ($pid_files as $pid_file) { 48 - $pid_data = Filesystem::readFile($pid_dir.'/'.$pid_file); 49 - $dict = json_decode($pid_data, true); 50 - if (!is_array($dict)) { 51 - // Just return a hanging reference, since control code needs to be 52 - // robust against unusual system states. 53 - $dict = array(); 54 - } 55 - $ref = PhabricatorDaemonReference::newFromDictionary($dict); 56 - $ref->setPIDFile($pid_dir.'/'.$pid_file); 57 - $results[] = $ref; 45 + $daemons[] = PhabricatorDaemonReference::newFromFile( 46 + $pid_dir.'/'.$pid_file); 58 47 } 59 48 60 - return $results; 49 + return $daemons; 61 50 } 62 51 63 52 protected final function loadAllRunningDaemons() { 64 - return id(new PhabricatorDaemonLogQuery()) 53 + $local_daemons = $this->loadRunningDaemons(); 54 + 55 + $local_ids = array(); 56 + foreach ($local_daemons as $daemon) { 57 + $daemon_log = $daemon->getDaemonLog(); 58 + 59 + if ($daemon_log) { 60 + $local_ids[] = $daemon_log->getID(); 61 + } 62 + } 63 + 64 + $remote_daemons = id(new PhabricatorDaemonLogQuery()) 65 65 ->setViewer(PhabricatorUser::getOmnipotentUser()) 66 + ->withoutIDs($local_ids) 66 67 ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) 67 68 ->execute(); 69 + 70 + return array_merge($local_daemons, $remote_daemons); 68 71 } 69 72 70 73 private function findDaemonClass($substring) { ··· 280 283 } 281 284 282 285 $console->writeErr(pht('Done.')."\n"); 283 - 284 286 return 0; 285 287 } 286 288
+2
src/applications/daemon/storage/PhabricatorDaemonLog.php
··· 13 13 protected $host; 14 14 protected $pid; 15 15 protected $argv; 16 + protected $explicitArgv; 16 17 protected $status; 17 18 18 19 public function getConfiguration() { 19 20 return array( 20 21 self::CONFIG_SERIALIZATION => array( 21 22 'argv' => self::SERIALIZATION_JSON, 23 + 'explicitArgv' => self::SERIALIZATION_JSON, 22 24 ), 23 25 ) + parent::getConfiguration(); 24 26 }
+18 -5
src/infrastructure/daemon/control/PhabricatorDaemonReference.php
··· 10 10 11 11 private $daemonLog; 12 12 13 + public static function newFromFile($path) { 14 + $pid_data = Filesystem::readFile($path); 15 + $dict = phutil_json_decode($pid_data); 16 + $ref = self::newFromDictionary($dict); 17 + $ref->pidFile = $path; 18 + return $ref; 19 + } 20 + 13 21 public static function newFromDictionary(array $dict) { 14 22 $ref = new PhabricatorDaemonReference(); 15 23 ··· 17 25 $ref->argv = idx($dict, 'argv', array()); 18 26 $ref->pid = idx($dict, 'pid'); 19 27 $ref->start = idx($dict, 'start'); 28 + 29 + $ref->daemonLog = id(new PhabricatorDaemonLog())->loadOneWhere( 30 + 'daemon = %s AND pid = %d AND dateCreated = %d', 31 + $ref->name, 32 + $ref->pid, 33 + $ref->start); 20 34 21 35 return $ref; 22 36 } ··· 66 80 return $this->start; 67 81 } 68 82 69 - public function setPIDFile($pid_file) { 70 - $this->pidFile = $pid_file; 71 - return $this; 83 + public function getPIDFile() { 84 + return $this->pidFile; 72 85 } 73 86 74 - public function getPIDFile() { 75 - return $this->pidFile; 87 + public function getDaemonLog() { 88 + return $this->daemonLog; 76 89 } 77 90 78 91 public function isRunning() {