Page MenuHomePhabricator

D14176.diff
No OneTemporary

D14176.diff

diff --git a/resources/sql/autopatches/20150928.drydock.rexpire.1.sql b/resources/sql/autopatches/20150928.drydock.rexpire.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150928.drydock.rexpire.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_drydock.drydock_resource
+ ADD until INT UNSIGNED;
diff --git a/src/applications/drydock/capability/DrydockDefaultViewCapability.php b/src/applications/drydock/capability/DrydockDefaultViewCapability.php
--- a/src/applications/drydock/capability/DrydockDefaultViewCapability.php
+++ b/src/applications/drydock/capability/DrydockDefaultViewCapability.php
@@ -8,4 +8,8 @@
return pht('Default Blueprint View Policy');
}
+ public function shouldAllowPublicPolicySetting() {
+ return true;
+ }
+
}
diff --git a/src/applications/drydock/controller/DrydockConsoleController.php b/src/applications/drydock/controller/DrydockConsoleController.php
--- a/src/applications/drydock/controller/DrydockConsoleController.php
+++ b/src/applications/drydock/controller/DrydockConsoleController.php
@@ -15,7 +15,6 @@
$nav->addFilter('blueprint', pht('Blueprints'));
$nav->addFilter('resource', pht('Resources'));
$nav->addFilter('lease', pht('Leases'));
- $nav->addFilter('log', pht('Logs'));
$nav->selectFilter(null);
@@ -31,6 +30,7 @@
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Blueprints'))
+ ->setFontIcon('fa-map-o')
->setHref($this->getApplicationURI('blueprint/'))
->addAttribute(
pht(
@@ -40,6 +40,7 @@
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Resources'))
+ ->setFontIcon('fa-map')
->setHref($this->getApplicationURI('resource/'))
->addAttribute(
pht('View and manage resources Drydock has built, like hosts.')));
@@ -47,16 +48,10 @@
$menu->addItem(
id(new PHUIObjectItemView())
->setHeader(pht('Leases'))
+ ->setFontIcon('fa-link')
->setHref($this->getApplicationURI('lease/'))
->addAttribute(pht('Manage leases on resources.')));
- $menu->addItem(
- id(new PHUIObjectItemView())
- ->setHeader(pht('Logs'))
- ->setHref($this->getApplicationURI('log/'))
- ->addAttribute(pht('View logs.')));
-
-
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Console'));
diff --git a/src/applications/drydock/controller/DrydockResourceViewController.php b/src/applications/drydock/controller/DrydockResourceViewController.php
--- a/src/applications/drydock/controller/DrydockResourceViewController.php
+++ b/src/applications/drydock/controller/DrydockResourceViewController.php
@@ -116,6 +116,14 @@
pht('Status'),
$status);
+ $until = $resource->getUntil();
+ if ($until) {
+ $until_display = phabricator_datetime($until, $viewer);
+ } else {
+ $until_display = phutil_tag('em', array(), pht('Never'));
+ }
+ $view->addProperty(pht('Expires'), $until_display);
+
$view->addProperty(
pht('Resource Type'),
$resource->getType());
diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php
--- a/src/applications/drydock/storage/DrydockLease.php
+++ b/src/applications/drydock/storage/DrydockLease.php
@@ -295,6 +295,15 @@
}
}
+ public function canUpdate() {
+ switch ($this->getStatus()) {
+ case DrydockLeaseStatus::STATUS_ACTIVE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public function scheduleUpdate($epoch = null) {
PhabricatorWorker::scheduleTask(
'DrydockLeaseUpdateWorker',
diff --git a/src/applications/drydock/storage/DrydockResource.php b/src/applications/drydock/storage/DrydockResource.php
--- a/src/applications/drydock/storage/DrydockResource.php
+++ b/src/applications/drydock/storage/DrydockResource.php
@@ -7,6 +7,7 @@
protected $phid;
protected $blueprintPHID;
protected $status;
+ protected $until;
protected $type;
protected $name;
@@ -32,6 +33,7 @@
'ownerPHID' => 'phid?',
'status' => 'text32',
'type' => 'text64',
+ 'until' => 'epoch?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_type' => array(
@@ -126,6 +128,10 @@
$this->isAllocated = true;
+ if ($new_status == DrydockResourceStatus::STATUS_ACTIVE) {
+ $this->didActivate();
+ }
+
return $this;
}
@@ -164,6 +170,8 @@
$this->isActivated = true;
+ $this->didActivate();
+
return $this;
}
@@ -181,14 +189,16 @@
}
}
- public function scheduleUpdate() {
+ public function scheduleUpdate($epoch = null) {
PhabricatorWorker::scheduleTask(
'DrydockResourceUpdateWorker',
array(
'resourcePHID' => $this->getPHID(),
+ 'isExpireTask' => ($epoch !== null),
),
array(
'objectPHID' => $this->getPHID(),
+ 'delayUntil' => $epoch,
));
}
@@ -209,6 +219,20 @@
if ($need_update) {
$this->scheduleUpdate();
}
+
+ $expires = $this->getUntil();
+ if ($expires) {
+ $this->scheduleUpdate($expires);
+ }
+ }
+
+ public function canUpdate() {
+ switch ($this->getStatus()) {
+ case DrydockResourceStatus::STATUS_ACTIVE:
+ return true;
+ default:
+ return false;
+ }
}
diff --git a/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php b/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
--- a/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
+++ b/src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
@@ -23,31 +23,15 @@
}
private function updateLease(DrydockLease $lease) {
- if ($lease->getStatus() != DrydockLeaseStatus::STATUS_ACTIVE) {
+ if (!$lease->canUpdate()) {
return;
}
- $viewer = $this->getViewer();
- $drydock_phid = id(new PhabricatorDrydockApplication())->getPHID();
-
- // Check if the lease has expired. If it is, we're going to send it a
- // release command. This command will be handled immediately below, it
- // just generates a command log and improves consistency.
- $now = PhabricatorTime::getNow();
- $expires = $lease->getUntil();
- if ($expires && ($expires <= $now)) {
- $command = DrydockCommand::initializeNewCommand($viewer)
- ->setTargetPHID($lease->getPHID())
- ->setAuthorPHID($drydock_phid)
- ->setCommand(DrydockCommand::COMMAND_RELEASE)
- ->save();
- }
+ $this->checkLeaseExpiration($lease);
$commands = $this->loadCommands($lease->getPHID());
foreach ($commands as $command) {
- if ($lease->getStatus() != DrydockLeaseStatus::STATUS_ACTIVE) {
- // Leases can't receive commands before they activate or after they
- // release.
+ if (!$lease->canUpdate()) {
break;
}
@@ -58,15 +42,7 @@
->save();
}
- // If this is the task which will eventually release the lease after it
- // expires but it is still active, reschedule the task to run after the
- // lease expires. This can happen if the lease's expiration was pushed
- // forward.
- if ($lease->getStatus() == DrydockLeaseStatus::STATUS_ACTIVE) {
- if ($this->getTaskDataValue('isExpireTask') && $expires) {
- throw new PhabricatorWorkerYieldException($expires - $now);
- }
- }
+ $this->yieldIfExpiringLease($lease);
}
private function processCommand(
diff --git a/src/applications/drydock/worker/DrydockResourceUpdateWorker.php b/src/applications/drydock/worker/DrydockResourceUpdateWorker.php
--- a/src/applications/drydock/worker/DrydockResourceUpdateWorker.php
+++ b/src/applications/drydock/worker/DrydockResourceUpdateWorker.php
@@ -11,18 +11,27 @@
$lock = PhabricatorGlobalLock::newLock($lock_key)
->lock(1);
- $resource = $this->loadResource($resource_phid);
- $this->updateResource($resource);
+ try {
+ $resource = $this->loadResource($resource_phid);
+ $this->updateResource($resource);
+ } catch (Exception $ex) {
+ $lock->unlock();
+ throw $ex;
+ }
$lock->unlock();
}
private function updateResource(DrydockResource $resource) {
+ if (!$resource->canUpdate()) {
+ return;
+ }
+
+ $this->checkResourceExpiration($resource);
+
$commands = $this->loadCommands($resource->getPHID());
foreach ($commands as $command) {
- if ($resource->getStatus() != DrydockResourceStatus::STATUS_ACTIVE) {
- // Resources can't receive commands before they activate or after they
- // release.
+ if (!$resource->canUpdate()) {
break;
}
@@ -32,6 +41,8 @@
->setIsConsumed(true)
->save();
}
+
+ $this->yieldIfExpiringResource($resource);
}
private function processCommand(
diff --git a/src/applications/drydock/worker/DrydockWorker.php b/src/applications/drydock/worker/DrydockWorker.php
--- a/src/applications/drydock/worker/DrydockWorker.php
+++ b/src/applications/drydock/worker/DrydockWorker.php
@@ -50,4 +50,68 @@
return $commands;
}
+ protected function checkLeaseExpiration(DrydockLease $lease) {
+ $this->checkObjectExpiration($lease);
+ }
+
+ protected function checkResourceExpiration(DrydockResource $resource) {
+ $this->checkObjectExpiration($resource);
+ }
+
+ private function checkObjectExpiration($object) {
+ // Check if the resource or lease has expired. If it has, we're going to
+ // send it a release command.
+
+ // This command is sent from within the update worker so it is handled
+ // immediately, but doing this generates a log and improves consistency.
+
+ $expires = $object->getUntil();
+ if (!$expires) {
+ return;
+ }
+
+ $now = PhabricatorTime::getNow();
+ if ($expires > $now) {
+ return;
+ }
+
+ $viewer = $this->getViewer();
+ $drydock_phid = id(new PhabricatorDrydockApplication())->getPHID();
+
+ $command = DrydockCommand::initializeNewCommand($viewer)
+ ->setTargetPHID($object->getPHID())
+ ->setAuthorPHID($drydock_phid)
+ ->setCommand(DrydockCommand::COMMAND_RELEASE)
+ ->save();
+ }
+
+ protected function yieldIfExpiringLease(DrydockLease $lease) {
+ if (!$lease->canUpdate()) {
+ return;
+ }
+
+ $this->yieldIfExpiring($lease->getUntil());
+ }
+
+ protected function yieldIfExpiringResource(DrydockResource $resource) {
+ if (!$resource->canUpdate()) {
+ return;
+ }
+
+ $this->yieldIfExpiring($resource->getUntil());
+ }
+
+ private function yieldIfExpiring($expires) {
+ if (!$expires) {
+ return;
+ }
+
+ if (!$this->getTaskDataValue('isExpireTask')) {
+ return;
+ }
+
+ $now = PhabricatorTime::getNow();
+ throw new PhabricatorWorkerYieldException($expires - $now);
+ }
+
}
diff --git a/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php
--- a/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php
+++ b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php
@@ -39,6 +39,13 @@
}
}
+ // When we lock tasks properly, this gets populated as a side effect. Just
+ // fake it when doing manual CLI stuff. This makes sure CLI yields have
+ // their expires times set properly.
+ foreach ($tasks as $task) {
+ $task->setServerTime(PhabricatorTime::getNow());
+ }
+
return $tasks;
}

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 26, 7:34 PM (3 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6723405
Default Alt Text
D14176.diff (11 KB)

Event Timeline