Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14023044
D10228.id24617.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D10228.id24617.diff
View Options
diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php
--- a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php
+++ b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php
@@ -53,6 +53,10 @@
$tag->setBackgroundColor(PHUITagView::COLOR_BLUE);
$tag->setName(pht('Waiting'));
break;
+ case PhabricatorDaemonLog::STATUS_EXITING:
+ $tag->setBackgroundColor(PHUITagView::COLOR_YELLOW);
+ $tag->setName(pht('Exiting'));
+ break;
case PhabricatorDaemonLog::STATUS_EXITED:
$tag->setBackgroundColor(PHUITagView::COLOR_GREY);
$tag->setName(pht('Exited'));
@@ -136,6 +140,10 @@
phutil_format_relative_time($unknown_time),
phutil_format_relative_time($wait_time));
break;
+ case PhabricatorDaemonLog::STATUS_EXITING:
+ $details = pht(
+ 'This daemon is shutting down gracefully.');
+ break;
case PhabricatorDaemonLog::STATUS_EXITED:
$details = pht(
'This daemon exited normally and is no longer running.');
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
@@ -8,6 +8,7 @@
$this->listen(PhutilDaemonOverseer::EVENT_DID_LAUNCH);
$this->listen(PhutilDaemonOverseer::EVENT_DID_LOG);
$this->listen(PhutilDaemonOverseer::EVENT_DID_HEARTBEAT);
+ $this->listen(PhutilDaemonOverseer::EVENT_WILL_GRACEFUL);
$this->listen(PhutilDaemonOverseer::EVENT_WILL_EXIT);
}
@@ -22,6 +23,9 @@
case PhutilDaemonOverseer::EVENT_DID_LOG:
$this->handleLogEvent($event);
break;
+ case PhutilDaemonOverseer::EVENT_WILL_GRACEFUL:
+ $this->handleGracefulEvent($event);
+ break;
case PhutilDaemonOverseer::EVENT_WILL_EXIT:
$this->handleExitEvent($event);
break;
@@ -86,6 +90,13 @@
}
}
+ private function handleGracefulEvent(PhutilEvent $event) {
+ $id = $event->getValue('id');
+
+ $daemon = $this->getDaemon($id);
+ $daemon->setStatus(PhabricatorDaemonLog::STATUS_EXITING)->save();
+ }
+
private function handleExitEvent(PhutilEvent $event) {
$id = $event->getValue('id');
diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php
--- a/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php
+++ b/src/applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php
@@ -9,11 +9,22 @@
->setSynopsis(
pht(
'Stop, then start the standard daemon loadout.'))
- ->setArguments(array());
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'graceful',
+ 'param' => 'seconds',
+ 'help' => pht(
+ 'Grace period for daemons to attempt a clean shutdown, in '.
+ 'seconds. Defaults to __15__ seconds.'),
+ 'default' => 15,
+ ),
+ ));
}
public function execute(PhutilArgumentParser $args) {
- $err = $this->executeStopCommand(array());
+ $graceful = $args->getArg('graceful');
+ $err = $this->executeStopCommand(array(), $graceful);
if ($err) {
return $err;
}
diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementStopWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementStopWorkflow.php
--- a/src/applications/daemon/management/PhabricatorDaemonManagementStopWorkflow.php
+++ b/src/applications/daemon/management/PhabricatorDaemonManagementStopWorkflow.php
@@ -13,6 +13,14 @@
->setArguments(
array(
array(
+ 'name' => 'graceful',
+ 'param' => 'seconds',
+ 'help' => pht(
+ 'Grace period for daemons to attempt a clean shutdown, in '.
+ 'seconds. Defaults to __15__ seconds.'),
+ 'default' => 15,
+ ),
+ array(
'name' => 'pids',
'wildcard' => true,
),
@@ -21,7 +29,8 @@
public function execute(PhutilArgumentParser $args) {
$pids = $args->getArg('pids');
- return $this->executeStopCommand($pids);
+ $graceful = $args->getArg('graceful');
+ return $this->executeStopCommand($pids, $graceful);
}
}
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
@@ -286,7 +286,7 @@
return 0;
}
- protected final function executeStopCommand(array $pids) {
+ protected final function executeStopCommand(array $pids, $grace_period) {
$console = PhutilConsole::getConsole();
$daemons = $this->loadRunningDaemons();
@@ -325,39 +325,20 @@
}
$all_daemons = $running;
- foreach ($running as $key => $daemon) {
- $pid = $daemon->getPID();
- $name = $daemon->getName();
- $console->writeErr(pht("Stopping daemon '%s' (%s)...", $name, $pid)."\n");
- if (!$daemon->isRunning()) {
- $console->writeErr(pht('Daemon is not running.')."\n");
- unset($running[$key]);
- $daemon->updateStatus(PhabricatorDaemonLog::STATUS_EXITED);
- } else {
- posix_kill($pid, SIGINT);
- }
+ // If we're doing a graceful shutdown, try SIGINT first.
+ if ($grace_period) {
+ $running = $this->sendSignal($running, SIGINT, $grace_period);
}
- $start = time();
- do {
- foreach ($running as $key => $daemon) {
- $pid = $daemon->getPID();
- if (!$daemon->isRunning()) {
- $console->writeOut(pht('Daemon %s exited normally.', $pid)."\n");
- unset($running[$key]);
- }
- }
- if (empty($running)) {
- break;
- }
- usleep(100000);
- } while (time() < $start + 15);
+ // If we still have daemons, SIGTERM them.
+ if ($running) {
+ $running = $this->sendSignal($running, SIGTERM, 15);
+ }
- foreach ($running as $key => $daemon) {
- $pid = $daemon->getPID();
- $console->writeErr(pht('Sending daemon %s a SIGKILL.', $pid)."\n");
- posix_kill($pid, SIGKILL);
+ // If the overseer is still alive, SIGKILL it.
+ if ($running) {
+ $this->sendSignal($running, SIGKILL, 0);
}
foreach ($all_daemons as $daemon) {
@@ -369,6 +350,49 @@
return 0;
}
+ private function sendSignal(array $daemons, $signo, $wait) {
+ $console = PhutilConsole::getConsole();
+
+ foreach ($daemons as $key => $daemon) {
+ $pid = $daemon->getPID();
+ $name = $daemon->getName();
+
+ switch ($signo) {
+ case SIGINT:
+ $message = pht("Interrupting daemon '%s' (%s)...", $name, $pid);
+ break;
+ case SIGTERM:
+ $message = pht("Terminating daemon '%s' (%s)...", $name, $pid);
+ break;
+ case SIGKILL:
+ $message = pht("Killing daemon '%s' (%s)...", $name, $pid);
+ break;
+ }
+
+ $console->writeOut("%s\n", $message);
+ posix_kill($pid, $signo);
+ }
+
+ if ($wait) {
+ $start = PhabricatorTime::getNow();
+ do {
+ foreach ($daemons as $key => $daemon) {
+ $pid = $daemon->getPID();
+ if (!$daemon->isRunning()) {
+ $console->writeOut(pht('Daemon %s exited.', $pid)."\n");
+ unset($daemons[$key]);
+ }
+ }
+ if (empty($daemons)) {
+ break;
+ }
+ usleep(100000);
+ } while (PhabricatorTime::getNow() < $start + $wait);
+ }
+
+ return $daemons;
+ }
+
private function freeActiveLeases() {
$task_table = id(new PhabricatorWorkerActiveTask());
$conn_w = $task_table->establishConnection('w');
diff --git a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
--- a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
+++ b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php
@@ -67,6 +67,7 @@
$status_running = PhabricatorDaemonLog::STATUS_RUNNING;
$status_unknown = PhabricatorDaemonLog::STATUS_UNKNOWN;
$status_wait = PhabricatorDaemonLog::STATUS_WAIT;
+ $status_exiting = PhabricatorDaemonLog::STATUS_EXITING;
$status_exited = PhabricatorDaemonLog::STATUS_EXITED;
$status_dead = PhabricatorDaemonLog::STATUS_DEAD;
@@ -77,7 +78,8 @@
$seen = $daemon->getDateModified();
$is_running = ($status == $status_running) ||
- ($status == $status_wait);
+ ($status == $status_wait) ||
+ ($status == $status_exiting);
// If we haven't seen the daemon recently, downgrade its status to
// unknown.
@@ -160,6 +162,7 @@
PhabricatorDaemonLog::STATUS_UNKNOWN,
PhabricatorDaemonLog::STATUS_RUNNING,
PhabricatorDaemonLog::STATUS_WAIT,
+ PhabricatorDaemonLog::STATUS_EXITING,
);
default:
throw new Exception("Unknown status '{$status}'!");
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
@@ -7,6 +7,7 @@
const STATUS_RUNNING = 'run';
const STATUS_DEAD = 'dead';
const STATUS_WAIT = 'wait';
+ const STATUS_EXITING = 'exiting';
const STATUS_EXITED = 'exit';
protected $daemon;
diff --git a/src/applications/daemon/view/PhabricatorDaemonLogListView.php b/src/applications/daemon/view/PhabricatorDaemonLogListView.php
--- a/src/applications/daemon/view/PhabricatorDaemonLogListView.php
+++ b/src/applications/daemon/view/PhabricatorDaemonLogListView.php
@@ -17,8 +17,7 @@
throw new Exception('Call setUser() before rendering!');
}
- $list = id(new PHUIObjectItemListView())
- ->setFlush(true);
+ $list = new PHUIObjectItemListView();
foreach ($this->daemonLogs as $log) {
$id = $log->getID();
$epoch = $log->getDateCreated();
@@ -43,6 +42,10 @@
'dead.'));
$item->addIcon('fa-times grey', pht('Dead'));
break;
+ case PhabricatorDaemonLog::STATUS_EXITING:
+ $item->addAttribute(pht('This daemon is exiting.'));
+ $item->addIcon('fa-check', pht('Exiting'));
+ break;
case PhabricatorDaemonLog::STATUS_EXITED:
$item->setDisabled(true);
$item->addAttribute(pht('This daemon exited cleanly.'));
diff --git a/src/applications/fact/daemon/PhabricatorFactDaemon.php b/src/applications/fact/daemon/PhabricatorFactDaemon.php
--- a/src/applications/fact/daemon/PhabricatorFactDaemon.php
+++ b/src/applications/fact/daemon/PhabricatorFactDaemon.php
@@ -8,7 +8,7 @@
public function run() {
$this->setEngines(PhabricatorFactEngine::loadAllEngines());
- while (true) {
+ while (!$this->shouldExit()) {
$iterators = $this->getAllApplicationIterators();
foreach ($iterators as $iterator_name => $iterator) {
$this->processIteratorWithCursor($iterator_name, $iterator);
diff --git a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
--- a/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
+++ b/src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
@@ -71,7 +71,7 @@
$futures = array();
$queue = array();
- while (true) {
+ while (!$this->shouldExit()) {
$pullable = $this->loadPullableRepositories($include, $exclude);
// If any repositories have the NEEDS_UPDATE flag set, pull them
@@ -422,6 +422,12 @@
new PhutilNumber($sleep_duration)));
$this->sleep(1);
+
+ if ($this->shouldExit()) {
+ $this->log(pht('Awakened from sleep by graceful shutdown!'));
+ return;
+ }
+
if ($this->loadRepositoryUpdateMessages()) {
$this->log(pht('Awakened from sleep by pending updates!'));
break;
diff --git a/src/infrastructure/daemon/bot/PhabricatorBot.php b/src/infrastructure/daemon/bot/PhabricatorBot.php
--- a/src/infrastructure/daemon/bot/PhabricatorBot.php
+++ b/src/infrastructure/daemon/bot/PhabricatorBot.php
@@ -103,7 +103,7 @@
foreach ($this->handlers as $handler) {
$handler->runBackgroundTasks();
}
- } while (true);
+ } while (!$this->shouldExit());
}
public function writeMessage(PhabricatorBotMessage $message) {
diff --git a/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php b/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php
--- a/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php
+++ b/src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php
@@ -31,7 +31,7 @@
// scans just to delete a handful of rows; wake up in a few hours.
$this->log(pht('All caught up, waiting for more garbage.'));
$this->sleep(4 * (60 * 60));
- } while (true);
+ } while (!$this->shouldExit());
}
diff --git a/src/infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php b/src/infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php
--- a/src/infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php
+++ b/src/infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php
@@ -40,7 +40,7 @@
}
$this->sleep($sleep);
- } while (true);
+ } while (!$this->shouldExit());
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 7, 10:01 PM (5 d, 6 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6724100
Default Alt Text
D10228.id24617.diff (13 KB)
Attached To
Mode
D10228: Send graceful shutdown signals to daemons in Phabricator
Attached
Detach File
Event Timeline
Log In to Comment