Page MenuHomePhabricator

D17538.id.diff
No OneTemporary

D17538.id.diff

diff --git a/src/daemon/PhutilDaemonHandle.php b/src/daemon/PhutilDaemonHandle.php
--- a/src/daemon/PhutilDaemonHandle.php
+++ b/src/daemon/PhutilDaemonHandle.php
@@ -23,6 +23,7 @@
private $stdoutBuffer;
private $shouldRestart = true;
private $shouldShutdown;
+ private $hibernating = false;
private function __construct() {
// <empty>
@@ -104,6 +105,29 @@
return (bool)$this->future;
}
+ public function isHibernating() {
+ return
+ !$this->isRunning() &&
+ !$this->isDone() &&
+ $this->hibernating;
+ }
+
+ public function wakeFromHibernation() {
+ if (!$this->isHibernating()) {
+ return $this;
+ }
+
+ $this->logMessage(
+ 'WAKE',
+ pht(
+ 'Process is being awakened from hibernation.'));
+
+ $this->restartAt = time();
+ $this->update();
+
+ return $this;
+ }
+
public function isDone() {
return (!$this->shouldRestart && !$this->isRunning());
}
@@ -318,6 +342,7 @@
$this->deadline = time() + $this->getRequiredHeartbeatFrequency();
$this->heartbeat = time() + self::getHeartbeatEventFrequency();
$this->stdoutBuffer = '';
+ $this->hibernating = false;
$this->future = $this->newExecFuture();
$this->future->start();
@@ -366,6 +391,7 @@
$config = idx($structure, 1);
$duration = (int)idx($config, 'duration', 0);
$this->restartAt = time() + $duration;
+ $this->hibernating = true;
$this->logMessage(
'ZZZZ',
pht(
diff --git a/src/daemon/PhutilDaemonOverseer.php b/src/daemon/PhutilDaemonOverseer.php
--- a/src/daemon/PhutilDaemonOverseer.php
+++ b/src/daemon/PhutilDaemonOverseer.php
@@ -187,6 +187,12 @@
foreach ($this->getDaemonPools() as $pool) {
$pool->updatePool();
+ if ($pool->isHibernating()) {
+ if ($this->shouldWakePool($pool)) {
+ $pool->wakeFromHibernation();
+ }
+ }
+
foreach ($pool->getFutures() as $future) {
$futures[] = $future;
}
@@ -476,5 +482,27 @@
return $should_reload;
}
+ private function shouldWakePool(PhutilDaemonPool $pool) {
+ $modules = $this->getModules();
+
+ $should_wake = false;
+ foreach ($modules as $module) {
+ try {
+ if ($module->shouldWakePool($pool)) {
+ $this->logMessage(
+ 'WAKE',
+ pht(
+ 'Waking pool "%s" (triggered by overseer module "%s").',
+ $pool->getPoolLabel(),
+ get_class($module)));
+ $should_wake = true;
+ }
+ } catch (Exception $ex) {
+ phlog($ex);
+ }
+ }
+
+ return $should_wake;
+ }
}
diff --git a/src/daemon/PhutilDaemonOverseerModule.php b/src/daemon/PhutilDaemonOverseerModule.php
--- a/src/daemon/PhutilDaemonOverseerModule.php
+++ b/src/daemon/PhutilDaemonOverseerModule.php
@@ -7,6 +7,7 @@
*/
abstract class PhutilDaemonOverseerModule extends Phobject {
+
/**
* This method is used to indicate to the overseer that daemons should reload.
*
@@ -15,6 +16,16 @@
abstract public function shouldReloadDaemons();
+ /**
+ * Should a hibernating daemon pool be awoken immediately?
+ *
+ * @return bool True to awaken the pool immediately.
+ */
+ public function shouldWakePool(PhutilDaemonPool $pool) {
+ return false;
+ }
+
+
public static function getAllModules() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
diff --git a/src/daemon/PhutilDaemonPool.php b/src/daemon/PhutilDaemonPool.php
--- a/src/daemon/PhutilDaemonPool.php
+++ b/src/daemon/PhutilDaemonPool.php
@@ -192,6 +192,45 @@
$this->updateAutoscale();
}
+ public function isHibernating() {
+ foreach ($this->getDaemons() as $daemon) {
+ if (!$daemon->isHibernating()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public function wakeFromHibernation() {
+ if (!$this->isHibernating()) {
+ return $this;
+ }
+
+ $this->logMessage(
+ 'WAKE',
+ pht(
+ 'Autoscale pool "%s" is being awakened from hibernation.',
+ $this->getPoolLabel()));
+
+ $did_wake_daemons = false;
+ foreach ($this->getDaemons() as $daemon) {
+ if ($daemon->isHibernating()) {
+ $daemon->wakeFromHibernation();
+ $did_wake_daemons = true;
+ }
+ }
+
+ if (!$did_wake_daemons) {
+ // TODO: Pools currently can't scale down to 0 daemons, but we should
+ // scale up immediately here once they can.
+ }
+
+ $this->updatePool();
+
+ return $this;
+ }
+
private function updateAutoscale() {
// Don't try to autoscale more than once per second. This mostly stops the
// logs from getting flooded in verbose mode.

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 10, 5:01 AM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7337331
Default Alt Text
D17538.id.diff (4 KB)

Event Timeline