private function updateLease(DrydockLease $lease) { if ($lease->getStatus() != DrydockLeaseStatus::STATUS_ACTIVE) { 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(); } $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. break; } $this->processCommand($lease, $command); $command->setIsConsumed(true)->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); } } }
private function activateLease(DrydockLease $lease) { $actual_status = $lease->getStatus(); if ($actual_status != DrydockLeaseStatus::STATUS_ACQUIRED) { throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease from wrong status ("%s").', $actual_status)); } $resource = $lease->getResource(); if (!$resource) { throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease with no resource.')); } $resource_status = $resource->getStatus(); if ($resource_status == DrydockResourceStatus::STATUS_PENDING) { // TODO: This is explicitly a temporary failure -- we are waiting for // the resource to come up. throw new Exception(pht('Resource still activating.')); } if ($resource_status != DrydockResourceStatus::STATUS_ACTIVE) { throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease on a dead resource (in status "%s").', $resource_status)); } // NOTE: We can race resource destruction here. Between the time we // performed the read above and now, the resource might have closed, so // we may activate leases on dead resources. At least for now, this seems // fine: a resource dying right before we activate a lease on it should not // be distinguisahble from a resource dying right after we activate a lease // on it. We end up with an active lease on a dead resource either way, and // can not prevent resources dying from lightning strikes. $blueprint = $resource->getBlueprint(); $blueprint->activateLease($resource, $lease); $this->validateActivatedLease($blueprint, $resource, $lease); }
private function buildPropertyListView(DrydockLease $lease, PhabricatorActionListView $actions) { $viewer = $this->getViewer(); $view = new PHUIPropertyListView(); $view->setActionList($actions); $view->addProperty(pht('Status'), DrydockLeaseStatus::getNameForStatus($lease->getStatus())); $view->addProperty(pht('Resource Type'), $lease->getResourceType()); $resource_phid = $lease->getResourcePHID(); if ($resource_phid) { $resource_display = $viewer->renderHandle($resource_phid); } else { $resource_display = phutil_tag('em', array(), pht('No Resource')); } $view->addProperty(pht('Resource'), $resource_display); $until = $lease->getUntil(); if ($until) { $until_display = phabricator_datetime($until, $viewer); } else { $until_display = phutil_tag('em', array(), pht('Never')); } $view->addProperty(pht('Expires'), $until_display); $attributes = $lease->getAttributes(); if ($attributes) { $view->addSectionHeader(pht('Attributes'), 'fa-list-ul'); foreach ($attributes as $key => $value) { $view->addProperty($key, $value); } } return $view; }
private function destroyLease(DrydockLease $lease) { $status = $lease->getStatus(); switch ($status) { case DrydockLeaseStatus::STATUS_RELEASED: case DrydockLeaseStatus::STATUS_BROKEN: break; default: throw new PhabricatorWorkerPermanentFailureException(pht('Unable to destroy lease ("%s"), lease has the wrong ' . 'status ("%s").', $lease->getPHID(), $status)); } $resource = $lease->getResource(); $blueprint = $resource->getBlueprint(); $blueprint->destroyLease($resource, $lease); $lease->setStatus(DrydockLeaseStatus::STATUS_DESTROYED)->save(); }
private function buildPropertyListView(DrydockLease $lease, PhabricatorActionListView $actions) { $view = new PHUIPropertyListView(); $view->setActionList($actions); switch ($lease->getStatus()) { case DrydockLeaseStatus::STATUS_ACTIVE: $status = pht('Active'); break; case DrydockLeaseStatus::STATUS_RELEASED: $status = pht('Released'); break; case DrydockLeaseStatus::STATUS_EXPIRED: $status = pht('Expired'); break; case DrydockLeaseStatus::STATUS_PENDING: $status = pht('Pending'); break; case DrydockLeaseStatus::STATUS_BROKEN: $status = pht('Broken'); break; default: $status = pht('Unknown'); break; } $view->addProperty(pht('Status'), $status); $view->addProperty(pht('Resource Type'), $lease->getResourceType()); $view->addProperty(pht('Resource'), $lease->getResourceID()); $attributes = $lease->getAttributes(); if ($attributes) { $view->addSectionHeader(pht('Attributes')); foreach ($attributes as $key => $value) { $view->addProperty($key, $value); } } return $view; }
/** * @task break */ protected function breakLease(DrydockLease $lease, Exception $ex) { switch ($lease->getStatus()) { case DrydockLeaseStatus::STATUS_BROKEN: case DrydockLeaseStatus::STATUS_RELEASED: case DrydockLeaseStatus::STATUS_DESTROYED: throw new PhutilProxyException(pht('Unexpected failure while destroying lease ("%s").', $lease->getPHID()), $ex); } $lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN)->save(); $lease->logEvent(DrydockLeaseActivationFailureLogType::LOGCONST, array('class' => get_class($ex), 'message' => $ex->getMessage())); $lease->awakenTasks(); $this->queueTask(__CLASS__, array('leasePHID' => $lease->getPHID()), array('objectPHID' => $lease->getPHID())); throw new PhabricatorWorkerPermanentFailureException(pht('Permanent failure while activating lease ("%s"): %s', $lease->getPHID(), $ex->getMessage())); }
protected function requireActiveLease(DrydockLease $lease) { $lease_status = $lease->getStatus(); switch ($lease_status) { case DrydockLeaseStatus::STATUS_PENDING: case DrydockLeaseStatus::STATUS_ACQUIRED: throw new PhabricatorWorkerYieldException(15); case DrydockLeaseStatus::STATUS_ACTIVE: return; default: throw new Exception(pht('Lease ("%s") is in bad state ("%s"), expected "%s".', $lease->getPHID(), $lease_status, DrydockLeaseStatus::STATUS_ACTIVE)); } }
protected function requireActiveLease(DrydockLease $lease) { $lease_status = $lease->getStatus(); switch ($lease_status) { case DrydockLeaseStatus::STATUS_ACQUIRED: // TODO: Temporary failure. throw new Exception(pht('Lease still activating.')); case DrydockLeaseStatus::STATUS_ACTIVE: return; default: // TODO: Permanent failure. throw new Exception(pht('Lease in bad state.')); } }