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 @@ -666,6 +666,26 @@ DrydockLease $lease) { $viewer = $this->getViewer(); + // If this lease is marked as already in the process of reclaiming a + // resource, don't let it reclaim another one until the first reclaim + // completes. This stops one lease from reclaiming a large number of + // resources if the reclaims take a while to complete. + $reclaiming_phid = $lease->getAttribute('drydock.reclaimingPHID'); + if ($reclaiming_phid) { + $reclaiming_resource = id(new DrydockResourceQuery()) + ->setViewer($viewer) + ->withPHIDs(array($reclaiming_phid)) + ->withStatuses( + array( + DrydockResourceStatus::STATUS_ACTIVE, + DrydockResourceStatus::STATUS_RELEASED, + )) + ->executeOne(); + if ($reclaiming_resource) { + return null; + } + } + $resources = id(new DrydockResourceQuery()) ->setViewer($viewer) ->withBlueprintPHIDs(array($blueprint->getPHID())) 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 @@ -241,16 +241,25 @@ DrydockLease $lease) { $viewer = $this->getViewer(); + // Mark the lease as reclaiming this resource. It won't be allowed to start + // another reclaim as long as this resource is still in the process of + // being reclaimed. + $lease->setAttribute('drydock.reclaimingPHID', $resource->getPHID()); + // When the resource releases, we we want to reawaken this task since it - // should be able to start building a new resource right away. + // should (usually) be able to start building a new resource right away. $worker_task_id = $this->getCurrentWorkerTaskID(); $command = DrydockCommand::initializeNewCommand($viewer) ->setTargetPHID($resource->getPHID()) ->setAuthorPHID($lease->getPHID()) ->setCommand(DrydockCommand::COMMAND_RECLAIM) - ->setProperty('awakenTaskIDs', array($worker_task_id)) - ->save(); + ->setProperty('awakenTaskIDs', array($worker_task_id)); + + $lease->openTransaction(); + $lease->save(); + $command->save(); + $lease->saveTransaction(); $resource->scheduleUpdate();