Changeset View
Changeset View
Standalone View
Standalone View
src/applications/drydock/worker/DrydockLeaseUpdateWorker.php
<?php | <?php | ||||
final class DrydockLeaseUpdateWorker extends DrydockWorker { | final class DrydockLeaseUpdateWorker extends DrydockWorker { | ||||
protected function doWork() { | protected function doWork() { | ||||
$lease_phid = $this->getTaskDataValue('leasePHID'); | $lease_phid = $this->getTaskDataValue('leasePHID'); | ||||
$hash = PhabricatorHash::digestForIndex($lease_phid); | $hash = PhabricatorHash::digestForIndex($lease_phid); | ||||
$lock_key = 'drydock.lease:'.$hash; | $lock_key = 'drydock.lease:'.$hash; | ||||
$lock = PhabricatorGlobalLock::newLock($lock_key) | $lock = PhabricatorGlobalLock::newLock($lock_key) | ||||
->lock(1); | ->lock(1); | ||||
try { | |||||
$lease = $this->loadLease($lease_phid); | $lease = $this->loadLease($lease_phid); | ||||
$this->updateLease($lease); | $this->updateLease($lease); | ||||
} catch (Exception $ex) { | |||||
$lock->unlock(); | |||||
throw $ex; | |||||
} | |||||
$lock->unlock(); | $lock->unlock(); | ||||
} | } | ||||
private function updateLease(DrydockLease $lease) { | 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()); | $commands = $this->loadCommands($lease->getPHID()); | ||||
foreach ($commands as $command) { | foreach ($commands as $command) { | ||||
if ($lease->getStatus() != DrydockLeaseStatus::STATUS_ACTIVE) { | if ($lease->getStatus() != DrydockLeaseStatus::STATUS_ACTIVE) { | ||||
// Leases can't receive commands before they activate or after they | // Leases can't receive commands before they activate or after they | ||||
// release. | // release. | ||||
break; | break; | ||||
} | } | ||||
$this->processCommand($lease, $command); | $this->processCommand($lease, $command); | ||||
$command | $command | ||||
->setIsConsumed(true) | ->setIsConsumed(true) | ||||
->save(); | ->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 processCommand( | private function processCommand( | ||||
DrydockLease $lease, | DrydockLease $lease, | ||||
DrydockCommand $command) { | DrydockCommand $command) { | ||||
switch ($command->getCommand()) { | switch ($command->getCommand()) { | ||||
case DrydockCommand::COMMAND_RELEASE: | case DrydockCommand::COMMAND_RELEASE: | ||||
$this->releaseLease($lease); | $this->releaseLease($lease); | ||||
Show All 30 Lines |