From cd2dd2a08f81d053d8d45e045006917bd7d14e98 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 28 Sep 2015 09:35:26 -0700 Subject: [PATCH] Give visual feedback when a Drydock resource or lease is releasing Summary: Ref T9252. Show the user when a resource or lease has a pending release command in queue. Test Plan: Released a resource and lease from the web UI. In both cases, saw a "releasing" tag and the action disable. Reviewers: hach-que, chad Reviewed By: chad Maniphest Tasks: T9252 Differential Revision: https://secure.phabricator.com/D14177 --- .../controller/DrydockLeaseViewController.php | 9 +++++++ .../DrydockResourceViewController.php | 9 +++++++ .../drydock/query/DrydockLeaseQuery.php | 26 ++++++++++++++++++- .../drydock/query/DrydockResourceQuery.php | 25 ++++++++++++++++++ .../drydock/storage/DrydockLease.php | 21 +++++++++++++++ .../drydock/storage/DrydockResource.php | 22 +++++++++++++++- 6 files changed, 110 insertions(+), 2 deletions(-) diff --git a/src/applications/drydock/controller/DrydockLeaseViewController.php b/src/applications/drydock/controller/DrydockLeaseViewController.php index bb748cceee..f37ac1a376 100644 --- a/src/applications/drydock/controller/DrydockLeaseViewController.php +++ b/src/applications/drydock/controller/DrydockLeaseViewController.php @@ -9,6 +9,7 @@ final class DrydockLeaseViewController extends DrydockLeaseController { $lease = id(new DrydockLeaseQuery()) ->setViewer($viewer) ->withIDs(array($id)) + ->needUnconsumedCommands(true) ->executeOne(); if (!$lease) { return new Aphront404Response(); @@ -21,6 +22,10 @@ final class DrydockLeaseViewController extends DrydockLeaseController { $header = id(new PHUIHeaderView()) ->setHeader($title); + if ($lease->isReleasing()) { + $header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing')); + } + $actions = $this->buildActionListView($lease); $properties = $this->buildPropertyListView($lease, $actions); @@ -78,6 +83,10 @@ final class DrydockLeaseViewController extends DrydockLeaseController { $id = $lease->getID(); $can_release = $lease->canRelease(); + if ($lease->isReleasing()) { + $can_release = false; + } + $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $lease, diff --git a/src/applications/drydock/controller/DrydockResourceViewController.php b/src/applications/drydock/controller/DrydockResourceViewController.php index d241b00808..23f81c5225 100644 --- a/src/applications/drydock/controller/DrydockResourceViewController.php +++ b/src/applications/drydock/controller/DrydockResourceViewController.php @@ -9,6 +9,7 @@ final class DrydockResourceViewController extends DrydockResourceController { $resource = id(new DrydockResourceQuery()) ->setViewer($viewer) ->withIDs(array($id)) + ->needUnconsumedCommands(true) ->executeOne(); if (!$resource) { return new Aphront404Response(); @@ -21,6 +22,10 @@ final class DrydockResourceViewController extends DrydockResourceController { ->setPolicyObject($resource) ->setHeader($title); + if ($resource->isReleasing()) { + $header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing')); + } + $actions = $this->buildActionListView($resource); $properties = $this->buildPropertyListView($resource, $actions); @@ -82,6 +87,10 @@ final class DrydockResourceViewController extends DrydockResourceController { ->setObject($resource); $can_release = $resource->canRelease(); + if ($resource->isReleasing()) { + $can_release = false; + } + $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $resource, diff --git a/src/applications/drydock/query/DrydockLeaseQuery.php b/src/applications/drydock/query/DrydockLeaseQuery.php index c7c770bbea..c5fb41ff56 100644 --- a/src/applications/drydock/query/DrydockLeaseQuery.php +++ b/src/applications/drydock/query/DrydockLeaseQuery.php @@ -7,7 +7,7 @@ final class DrydockLeaseQuery extends DrydockQuery { private $resourcePHIDs; private $statuses; private $datasourceQuery; - private $needCommands; + private $needUnconsumedCommands; public function withIDs(array $ids) { $this->ids = $ids; @@ -34,6 +34,11 @@ final class DrydockLeaseQuery extends DrydockQuery { return $this; } + public function needUnconsumedCommands($need) { + $this->needUnconsumedCommands = $need; + return $this; + } + public function newResultObject() { return new DrydockLease(); } @@ -71,6 +76,25 @@ final class DrydockLeaseQuery extends DrydockQuery { return $leases; } + protected function didFilterPage(array $leases) { + if ($this->needUnconsumedCommands) { + $commands = id(new DrydockCommandQuery()) + ->setViewer($this->getViewer()) + ->setParentQuery($this) + ->withTargetPHIDs(mpull($leases, 'getPHID')) + ->withConsumed(false) + ->execute(); + $commands = mgroup($commands, 'getTargetPHID'); + + foreach ($leases as $lease) { + $list = idx($commands, $lease->getPHID(), array()); + $lease->attachUnconsumedCommands($list); + } + } + + return $leases; + } + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); diff --git a/src/applications/drydock/query/DrydockResourceQuery.php b/src/applications/drydock/query/DrydockResourceQuery.php index d15b737141..c477da20b5 100644 --- a/src/applications/drydock/query/DrydockResourceQuery.php +++ b/src/applications/drydock/query/DrydockResourceQuery.php @@ -8,6 +8,7 @@ final class DrydockResourceQuery extends DrydockQuery { private $types; private $blueprintPHIDs; private $datasourceQuery; + private $needUnconsumedCommands; public function withIDs(array $ids) { $this->ids = $ids; @@ -39,6 +40,11 @@ final class DrydockResourceQuery extends DrydockQuery { return $this; } + public function needUnconsumedCommands($need) { + $this->needUnconsumedCommands = $need; + return $this; + } + public function newResultObject() { return new DrydockResource(); } @@ -69,6 +75,25 @@ final class DrydockResourceQuery extends DrydockQuery { return $resources; } + protected function didFilterPage(array $resources) { + if ($this->needUnconsumedCommands) { + $commands = id(new DrydockCommandQuery()) + ->setViewer($this->getViewer()) + ->setParentQuery($this) + ->withTargetPHIDs(mpull($resources, 'getPHID')) + ->withConsumed(false) + ->execute(); + $commands = mgroup($commands, 'getTargetPHID'); + + foreach ($resources as $resource) { + $list = idx($commands, $resource->getPHID(), array()); + $resource->attachUnconsumedCommands($list); + } + } + + return $resources; + } + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php index bb65b982b6..c5834f0136 100644 --- a/src/applications/drydock/storage/DrydockLease.php +++ b/src/applications/drydock/storage/DrydockLease.php @@ -11,6 +11,8 @@ final class DrydockLease extends DrydockDAO protected $status = DrydockLeaseStatus::STATUS_PENDING; private $resource = self::ATTACHABLE; + private $unconsumedCommands = self::ATTACHABLE; + private $releaseOnDestruction; private $isAcquired = false; private $isActivated = false; @@ -104,6 +106,25 @@ final class DrydockLease extends DrydockDAO return ($this->resource !== null); } + public function getUnconsumedCommands() { + return $this->assertAttached($this->unconsumedCommands); + } + + public function attachUnconsumedCommands(array $commands) { + $this->unconsumedCommands = $commands; + return $this; + } + + public function isReleasing() { + foreach ($this->getUnconsumedCommands() as $command) { + if ($command->getCommand() == DrydockCommand::COMMAND_RELEASE) { + return true; + } + } + + return false; + } + public function queueForActivation() { if ($this->getID()) { throw new Exception( diff --git a/src/applications/drydock/storage/DrydockResource.php b/src/applications/drydock/storage/DrydockResource.php index f46383a84c..ab968c2249 100644 --- a/src/applications/drydock/storage/DrydockResource.php +++ b/src/applications/drydock/storage/DrydockResource.php @@ -8,7 +8,6 @@ final class DrydockResource extends DrydockDAO protected $blueprintPHID; protected $status; protected $until; - protected $type; protected $name; protected $attributes = array(); @@ -16,6 +15,8 @@ final class DrydockResource extends DrydockDAO protected $ownerPHID; private $blueprint = self::ATTACHABLE; + private $unconsumedCommands = self::ATTACHABLE; + private $isAllocated = false; private $isActivated = false; private $activateWhenAllocated = false; @@ -80,6 +81,25 @@ final class DrydockResource extends DrydockDAO return $this; } + public function getUnconsumedCommands() { + return $this->assertAttached($this->unconsumedCommands); + } + + public function attachUnconsumedCommands(array $commands) { + $this->unconsumedCommands = $commands; + return $this; + } + + public function isReleasing() { + foreach ($this->getUnconsumedCommands() as $command) { + if ($command->getCommand() == DrydockCommand::COMMAND_RELEASE) { + return true; + } + } + + return false; + } + public function setActivateWhenAllocated($activate) { $this->activateWhenAllocated = $activate; return $this;