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 releaseLease(DrydockLease $lease)
 {
     $lease->openTransaction();
     $lease->setStatus(DrydockLeaseStatus::STATUS_RELEASED)->save();
     // TODO: Hold slot locks until destruction?
     DrydockSlotLock::releaseLocks($lease->getPHID());
     $lease->saveTransaction();
     PhabricatorWorker::scheduleTask('DrydockLeaseDestroyWorker', array('leasePHID' => $lease->getPHID()), array('objectPHID' => $lease->getPHID()));
     $resource = $lease->getResource();
     $blueprint = $resource->getBlueprint();
     $blueprint->didReleaseLease($resource, $lease);
 }
 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();
 }
 /**
  * @task destroy
  */
 private function destroyLease(DrydockLease $lease)
 {
     $resource = $lease->getResource();
     if ($resource) {
         $blueprint = $resource->getBlueprint();
         $blueprint->destroyLease($resource, $lease);
     }
     DrydockSlotLock::releaseLocks($lease->getPHID());
     $lease->setStatus(DrydockLeaseStatus::STATUS_DESTROYED)->save();
     $lease->logEvent(DrydockLeaseDestroyedLogType::LOGCONST);
     $lease->awakenTasks();
 }