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

More phd stuff.

This commit is contained in:
epriestley 2011-03-14 15:43:56 -07:00
parent 2b6f16dccd
commit bf196910b0
6 changed files with 328 additions and 69 deletions

View file

@ -21,58 +21,24 @@ $root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php'; require_once $root.'/scripts/__init_script__.php';
require_once $root.'/scripts/__init_env__.php'; require_once $root.'/scripts/__init_env__.php';
phutil_require_module('phabricator', 'infrastructure/daemon/control');
$control = new PhabricatorDaemonControl();
$phd_dir = PhabricatorEnv::getEnvConfig('phd.pid-directory'); $phd_dir = PhabricatorEnv::getEnvConfig('phd.pid-directory');
$pid_dir = $phd_dir.'/pid'; $pid_dir = $phd_dir.'/pid';
switch (isset($argv[1]) ? $argv[1] : 'help') { switch (isset($argv[1]) ? $argv[1] : 'help') {
case 'list': case 'list':
phutil_require_module('phutil', 'console'); $err = $control->executeListCommand();
exit($err);
$loader = new PhutilSymbolLoader();
$symbols = $loader
->setAncestorClass('PhutilDaemon')
->selectSymbolsWithoutLoading();
$symbols = igroup($symbols, 'library');
foreach ($symbols as $library => $symbol_list) {
echo phutil_console_format("Daemons in library __%s__:\n", $library);
foreach ($symbol_list as $symbol) {
echo " ".$symbol['name']."\n";
}
echo "\n";
}
break;
case 'status': case 'status':
$pid_descs = Filesystem::listDirectory($pid_dir); $err = $control->executeStatusCommand();
if (!$pid_descs) { exit($err);
echo "There are no running Phabricator daemons.\n";
} else {
printf(
"%-5s\t%-24s\t%s\n",
"PID",
"Started",
"Daemon");
foreach ($pid_descs as $pid_file) {
$data = Filesystem::readFile($pid_dir.'/'.$pid_file);
$data = json_decode($data, true);
$pid = idx($data, 'pid', '?'); case 'stop':
$name = idx($data, 'name', '?'); $err = $control->executeStopCommand();
$since = idx($data, 'start') exit($err);
? date('M j Y, g:i:s A', $data['start'])
: '?';
printf(
"%5s\t%-24s\t%s\n",
$pid,
$since,
$name);
}
}
break;
case 'launch': case 'launch':
phutil_require_module('phutil', 'moduleutils'); phutil_require_module('phutil', 'moduleutils');
@ -82,6 +48,8 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
throw new Exception("Daemon name required!"); throw new Exception("Daemon name required!");
} }
$pass = array_slice($argv, 3);
$n = 1; $n = 1;
if (is_numeric($daemon)) { if (is_numeric($daemon)) {
$n = $daemon; $n = $daemon;
@ -92,6 +60,7 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
if (!$daemon) { if (!$daemon) {
throw new Exception("Daemon name required!"); throw new Exception("Daemon name required!");
} }
$pass = array_slice($argv, 4);
} }
$loader = new PhutilSymbolLoader(); $loader = new PhutilSymbolLoader();
@ -131,12 +100,23 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
Filesystem::assertIsDirectory($pid_dir); Filesystem::assertIsDirectory($pid_dir);
Filesystem::assertWritable($pid_dir); Filesystem::assertWritable($pid_dir);
foreach ($pass as $key => $arg) {
$pass[$key] = escapeshellarg($arg);
}
echo "Starting {$n} x {$daemon}"; echo "Starting {$n} x {$daemon}";
chdir($launch_daemon);
for ($ii = 0; $ii < $n; $ii++) { for ($ii = 0; $ii < $n; $ii++) {
list($stdout, $stderr) = execx( list($stdout, $stderr) = execx(
"(cd %s && ./launch_daemon.php %s --daemonize --phd=%s)", "./launch_daemon.php ".
$launch_daemon, "%s ".
"--load-phutil-library=%s ".
"--daemonize ".
"--phd=%s ".
implode(' ', $pass),
$daemon, $daemon,
phutil_get_library_root('phabricator'),
$pid_dir); $pid_dir);
echo "."; echo ".";
} }
@ -191,27 +171,6 @@ switch (isset($argv[1]) ? $argv[1] : 'help') {
case '--help': case '--help':
case 'help': case 'help':
default: default:
echo <<<EOHELP $err = $control->executeHelpCommand();
phd - phabricator daemon launcher exit($err);
launch <daemon>
Start a daemon.
list
List available daemons.
stop
Stop all daemons.
status
List running daemons.
stop
Stop all running daemons.
parse-commit <rXnnnn>
Parse a single commit.
EOHELP;
exit(1);
} }

View file

@ -205,7 +205,9 @@ phutil_register_library_map(array(
'PhabricatorController' => 'applications/base/controller/base', 'PhabricatorController' => 'applications/base/controller/base',
'PhabricatorDaemon' => 'infrastructure/daemon/base', 'PhabricatorDaemon' => 'infrastructure/daemon/base',
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console', 'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
'PhabricatorDaemonController' => 'applications/daemon/controller/base', 'PhabricatorDaemonController' => 'applications/daemon/controller/base',
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline', 'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent', 'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/timelineevent',
'PhabricatorDirectoryCategory' => 'applications/directory/storage/category', 'PhabricatorDirectoryCategory' => 'applications/directory/storage/category',

View file

@ -0,0 +1,192 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorDaemonControl {
public function executeListCommand() {
$symbols = $this->loadAvailableDaemonClasses();
$symbols = igroup($symbols, 'library');
echo "\n";
foreach ($symbols as $library => $symbol_list) {
echo phutil_console_format("Daemons in library __%s__:\n", $library);
foreach ($symbol_list as $symbol) {
echo " ".$symbol['name']."\n";
}
echo "\n";
}
return 0;
}
public function executeStatusCommand() {
$daemons = $this->loadRunningDaemons();
if (!$daemons) {
echo "There are no running Phabricator daemons.\n";
return 0;
}
printf(
"%-5s\t%-24s\t%s\n",
"PID",
"Started",
"Daemon");
foreach ($daemons as $daemon) {
printf(
"%5s\t%-24s\t%s\n",
$daemon->getPID(),
$daemon->getEpochStarted()
? date('M j Y, g:i:s A', $daemon->getEpochStarted())
: null,
$daemon->getName());
}
return 0;
}
public function executeStopCommand() {
$daemons = $this->loadRunningDaemons();
if (!$daemons) {
echo "There are no running Phabricator daemons.\n";
return 0;
}
$running = $daemons;
foreach ($running as $key => $daemon) {
$pid = $daemon->getPID();
$name = $daemon->getName();
echo "Stopping daemon '{$name}' ({$pid})...\n";
if (!$daemon->isRunning()) {
echo "Daemon is not running.\n";
unset($running[$key]);
} else {
posix_kill($pid, SIGINT);
}
}
$start = time();
do {
foreach ($running as $key => $daemon) {
$pid = $daemon->getPID();
if (!$daemon->isRunning()) {
echo "Daemon {$pid} exited normally.\n";
unset($running[$key]);
}
}
if (empty($running)) {
break;
}
usleep(100000);
} while (time() < $start + 15);
foreach ($running as $key => $daemon) {
$pid = $daemon->getPID();
echo "KILLing daemon {$pid}.\n";
posix_kill($pid, SIGKILL);
}
foreach ($daemons as $daemon) {
if ($daemon->getPIDFile()) {
Filesystem::remove($daemon->getPIDFile());
}
}
}
public function executeHelpCommand() {
echo phutil_console_format(<<<EOHELP
**NAME**
**phd** - phabricator daemon launcher
**COMMAND REFERENCE**
**launch** [__n__] __daemon__
Start a daemon (or n copies of a daemon).
**list**
List available daemons.
**stop**
Stop all daemons.
**status**
List running daemons.
**stop**
Stop all running daemons.
**help**
Show this help.
**parse-commit** __rXnnnn__
Parse a single commit.
EOHELP
);
return 1;
}
protected function getControlDirectory($dir) {
return PhabricatorEnv::getEnvConfig('phd.pid-directory').'/'.$dir;
}
protected function loadAvailableDaemonClasses() {
$loader = new PhutilSymbolLoader();
return $loader
->setAncestorClass('PhutilDaemon')
->selectSymbolsWithoutLoading();
}
protected function loadRunningDaemons() {
$results = array();
$pid_dir = $this->getControlDirectory('pid');
$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;
}
return $results;
}
protected function killDaemon(PhabricatorDaemonReference $ref) {
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'infrastructure/daemon/control/reference');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phutil', 'console');
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'symbols');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorDaemonControl.php');

View file

@ -0,0 +1,76 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorDaemonReference {
private $name;
private $pid;
private $start;
private $pidFile;
public static function newFromDictionary(array $dict) {
$ref = new PhabricatorDaemonReference();
$ref->name = idx($dict, 'name', 'Unknown');
$ref->pid = idx($dict, 'pid');
$ref->start = idx($dict, 'start');
return $ref;
}
public function getPID() {
return $this->pid;
}
public function getName() {
return $this->name;
}
public function getEpochStarted() {
return $this->start;
}
public function setPIDFile($pid_file) {
$this->pidFile = $pid_file;
return $this;
}
public function getPIDFile() {
return $this->pidFile;
}
public function isRunning() {
$pid = $this->getPID();
if (!$pid) {
return false;
}
return posix_kill($pid, 0);
}
public function waitForExit($seconds) {
$start = time();
while (time() < $start + $seconds) {
usleep(100000);
if (!$this->isRunning()) {
return true;
}
}
return !$this->isRunning();
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorDaemonReference.php');