diff --git a/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockAmazonEC2HostBlueprintImplementation.php @@ -71,6 +71,19 @@ return $platform_match && $custom_match; } + protected function executeInitializePendingResource( + DrydockResource $resource, + DrydockLease $lease) { + + // We must set the platform so that other allocators will lease + // against it successfully. + $resource + ->setAttribute( + 'platform', + $this->getDetail('platform')) + ->save(); + } + protected function executeAllocateResource( DrydockResource $resource, DrydockLease $lease) { diff --git a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php @@ -366,6 +366,10 @@ return true; } + abstract protected function executeInitializePendingResource( + DrydockResource $resource, + DrydockLease $lease); + abstract protected function executeAllocateResource( DrydockResource $resource, DrydockLease $lease); @@ -440,6 +444,25 @@ $resource->saveTransaction(); } + final public function initializePendingResource( + DrydockResource $resource, + DrydockLease $lease) { + + $scope = $this->pushActiveScope($resource, $lease); + + $this->log(pht( + 'Blueprint \'%s\': Initializing Resource for \'%s\'', + $this->getBlueprintClass(), + $lease->getLeaseName())); + + try { + $this->executeInitializePendingResource($resource, $lease); + } catch (Exception $ex) { + $this->logException($ex); + throw $ex; + } + } + final public function allocateResource( DrydockResource $resource, DrydockLease $lease) { @@ -572,7 +595,7 @@ } } - private function pushActiveScope( + public function pushActiveScope( DrydockResource $resource = null, DrydockLease $lease = null) { diff --git a/src/applications/drydock/blueprint/DrydockMinMaxBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockMinMaxBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockMinMaxBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockMinMaxBlueprintImplementation.php @@ -50,12 +50,14 @@ 'of %d.', count($pool), $max_count)); + return true; } else { $this->log(pht( 'Will deny resource allocation because %d is less than the maximum '. 'of %d.', count($pool), $max_count)); + return false; } } diff --git a/src/applications/drydock/blueprint/DrydockMinMaxExpiryBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockMinMaxExpiryBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockMinMaxExpiryBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockMinMaxExpiryBlueprintImplementation.php @@ -28,7 +28,7 @@ $pool_copy = array(); foreach ($pool as $resource) { $lifetime = $now - $resource->getDateCreated(); - if ($lifetime > $expiry) { + if ($lifetime <= $expiry) { $pool_copy[] = $resource; } } diff --git a/src/applications/drydock/blueprint/DrydockMinMaxTestBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockMinMaxTestBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockMinMaxTestBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockMinMaxTestBlueprintImplementation.php @@ -19,6 +19,10 @@ return pht('Used to test min / max counts.'); } + protected function executeInitializePendingResource( + DrydockResource $resource, + DrydockLease $lease) {} + protected function executeAllocateResource( DrydockResource $resource, DrydockLease $lease) { diff --git a/src/applications/drydock/blueprint/DrydockPreallocatedHostBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockPreallocatedHostBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockPreallocatedHostBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockPreallocatedHostBlueprintImplementation.php @@ -19,6 +19,10 @@ return false; } + protected function executeInitializePendingResource( + DrydockResource $resource, + DrydockLease $lease) {} + protected function executeAllocateResource( DrydockResource $resource, DrydockLease $lease) { diff --git a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php @@ -33,6 +33,10 @@ return $context->getCurrentResourceLeaseCount() === 0; } + protected function executeInitializePendingResource( + DrydockResource $resource, + DrydockLease $lease) {} + protected function executeAllocateResource( DrydockResource $resource, DrydockLease $lease) { diff --git a/src/applications/drydock/controller/DrydockLeaseViewController.php b/src/applications/drydock/controller/DrydockLeaseViewController.php --- a/src/applications/drydock/controller/DrydockLeaseViewController.php +++ b/src/applications/drydock/controller/DrydockLeaseViewController.php @@ -37,7 +37,8 @@ $logs = id(new DrydockLogQuery()) ->setViewer($viewer) ->withLeaseIDs(array($lease->getID())) - ->executeWithOffsetPager($pager); + ->execute(); +// ->executeWithOffsetPager($pager); $log_table = id(new DrydockLogListView()) ->setUser($viewer) diff --git a/src/applications/drydock/worker/DrydockAllocatorWorker.php b/src/applications/drydock/worker/DrydockAllocatorWorker.php --- a/src/applications/drydock/worker/DrydockAllocatorWorker.php +++ b/src/applications/drydock/worker/DrydockAllocatorWorker.php @@ -82,7 +82,7 @@ $blueprints = $this->loadAllBlueprints(); $lock = PhabricatorGlobalLock::newLock('drydockallocation'); - $lock->lock(10000); + $lock->lock(1000000); // TODO: Policy stuff. $pool = id(new DrydockResource())->loadAllWhere( @@ -216,6 +216,8 @@ try { foreach ($blueprints as $key => $candidate_blueprint) { + $scope = $candidate_blueprint->pushActiveScope(null, $lease); + $rpool = idx($resources_per_blueprint, $key, array()); if (!$candidate_blueprint->canAllocateMoreResources($rpool)) { $this->logToDrydock( @@ -326,6 +328,17 @@ $this->logToDrydock( pht('Moved the resource to the pending status.')); + // We must allow some initial set up of resource attributes within the + // lock such that when we exit, method calls to canAllocateLease will + // succeed even for pending resources. + $this->logToDrydock( + pht('Started initialization of pending resource.')); + + $blueprint->initializePendingResource($resource, $lease); + + $this->logToDrydock( + pht('Finished initialization of pending resource.')); + $lock->unlock(); } catch (Exception $ex) { $lock->unlock();