Index: scripts/drydock/drydock_control.php =================================================================== --- scripts/drydock/drydock_control.php +++ scripts/drydock/drydock_control.php @@ -15,7 +15,6 @@ $args->parseStandardArguments(); $workflows = array( - new DrydockManagementWaitForLeaseWorkflow(), new DrydockManagementLeaseWorkflow(), new DrydockManagementCloseWorkflow(), new DrydockManagementReleaseWorkflow(), Index: src/__phutil_library_map__.php =================================================================== --- src/__phutil_library_map__.php +++ src/__phutil_library_map__.php @@ -671,7 +671,6 @@ 'DrydockManagementCreateResourceWorkflow' => 'applications/drydock/management/DrydockManagementCreateResourceWorkflow.php', 'DrydockManagementLeaseWorkflow' => 'applications/drydock/management/DrydockManagementLeaseWorkflow.php', 'DrydockManagementReleaseWorkflow' => 'applications/drydock/management/DrydockManagementReleaseWorkflow.php', - 'DrydockManagementWaitForLeaseWorkflow' => 'applications/drydock/management/DrydockManagementWaitForLeaseWorkflow.php', 'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php', 'DrydockPHIDTypeBlueprint' => 'applications/drydock/phid/DrydockPHIDTypeBlueprint.php', 'DrydockPHIDTypeLease' => 'applications/drydock/phid/DrydockPHIDTypeLease.php', @@ -3099,7 +3098,6 @@ 'DrydockManagementCreateResourceWorkflow' => 'DrydockManagementWorkflow', 'DrydockManagementLeaseWorkflow' => 'DrydockManagementWorkflow', 'DrydockManagementReleaseWorkflow' => 'DrydockManagementWorkflow', - 'DrydockManagementWaitForLeaseWorkflow' => 'DrydockManagementWorkflow', 'DrydockManagementWorkflow' => 'PhutilArgumentWorkflow', 'DrydockPHIDTypeBlueprint' => 'PhabricatorPHIDType', 'DrydockPHIDTypeLease' => 'PhabricatorPHIDType', Index: src/applications/drydock/controller/DrydockBlueprintListController.php =================================================================== --- src/applications/drydock/controller/DrydockBlueprintListController.php +++ src/applications/drydock/controller/DrydockBlueprintListController.php @@ -53,4 +53,14 @@ return $view; } + public function buildApplicationCrumbs() { + $crumbs = parent::buildApplicationCrumbs(); + $crumbs->addAction( + id(new PHUIListItemView()) + ->setName(pht('New Blueprint')) + ->setHref($this->getApplicationURI('/blueprint/create/')) + ->setIcon('create')); + return $crumbs; + } + } Index: src/applications/drydock/management/DrydockManagementLeaseWorkflow.php =================================================================== --- src/applications/drydock/management/DrydockManagementLeaseWorkflow.php +++ src/applications/drydock/management/DrydockManagementLeaseWorkflow.php @@ -38,38 +38,16 @@ $attributes = $options->parse($attributes); } - $lease = new DrydockLease(); - $lease->setResourceType($resource_type); + PhabricatorWorker::setRunAllTasksInProcess(true); + + $lease = id(new DrydockLease()) + ->setResourceType($resource_type); if ($attributes) { $lease->setAttributes($attributes); } - $lease->queueForActivation(); - - $root = dirname(phutil_get_library_root('phabricator')); - $wait = new ExecFuture( - 'php -f %s wait-for-lease --id %s', - $root.'/scripts/drydock/drydock_control.php', - $lease->getID()); - - $cursor = 0; - foreach (Futures(array($wait))->setUpdateInterval(1) as $key => $future) { - if ($future) { - $future->resolvex(); - break; - } - - $logs = id(new DrydockLogQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withLeaseIDs(array($lease->getID())) - ->execute(); - - if ($logs) { - foreach ($logs as $log) { - $console->writeErr("%s\n", $log->getMessage()); - } - $cursor = max(mpull($logs, 'getID')); - } - } + $lease + ->queueForActivation() + ->waitUntilActive(); $console->writeOut("Acquired Lease %s\n", $lease->getID()); return 0; Index: src/applications/drydock/management/DrydockManagementWaitForLeaseWorkflow.php =================================================================== --- src/applications/drydock/management/DrydockManagementWaitForLeaseWorkflow.php +++ /dev/null @@ -1,40 +0,0 @@ -setName('wait-for-lease') - ->setSynopsis('Wait for a lease to become available.') - ->setArguments( - array( - array( - 'name' => 'id', - 'param' => 'lease_id', - 'help' => 'Lease ID to wait for.', - ), - )); - } - - public function execute(PhutilArgumentParser $args) { - $lease_id = $args->getArg('id'); - if (!$lease_id) { - throw new PhutilArgumentUsageException( - "Specify a lease ID with `--id`."); - } - - $console = PhutilConsole::getConsole(); - - $lease = id(new DrydockLease())->load($lease_id); - if (!$lease) { - $console->writeErr("No such lease.\n"); - return 1; - } else { - $lease->waitUntilActive(); - $console->writeErr("Lease active.\n"); - return 0; - } - } - -} Index: src/applications/drydock/query/DrydockLogQuery.php =================================================================== --- src/applications/drydock/query/DrydockLogQuery.php +++ src/applications/drydock/query/DrydockLogQuery.php @@ -40,10 +40,6 @@ foreach ($logs as $key => $log) { $resource = idx($resources, $log->getResourceID()); - if (!$resource) { - unset($logs[$key]); - continue; - } $log->attachResource($resource); } Index: src/applications/drydock/storage/DrydockLease.php =================================================================== --- src/applications/drydock/storage/DrydockLease.php +++ src/applications/drydock/storage/DrydockLease.php @@ -91,23 +91,17 @@ $this->setStatus(DrydockLeaseStatus::STATUS_PENDING); $this->save(); - // NOTE: Prevent a race where some eager worker quickly grabs the task - // before we can save the Task ID. + $task = PhabricatorWorker::scheduleTask( + 'DrydockAllocatorWorker', + $this->getID()); - $this->openTransaction(); - $this->beginReadLocking(); + // NOTE: Scheduling the task might execute it in-process, if we're running + // from a CLI script. Reload the lease to make sure we have the most + // up-to-date information. Normally, this has no effect. + $this->reload(); - $this->reload(); - - $task = PhabricatorWorker::scheduleTask( - 'DrydockAllocatorWorker', - $this->getID()); - - $this->setTaskID($task->getID()); - $this->save(); - - $this->endReadLocking(); - $this->saveTransaction(); + $this->setTaskID($task->getID()); + $this->save(); return $this; } @@ -163,6 +157,8 @@ case DrydockLeaseStatus::STATUS_PENDING: case DrydockLeaseStatus::STATUS_ACQUIRING: break; + default: + throw new Exception("Unknown status??"); } } Index: src/applications/drydock/storage/DrydockLog.php =================================================================== --- src/applications/drydock/storage/DrydockLog.php +++ src/applications/drydock/storage/DrydockLog.php @@ -16,7 +16,7 @@ ) + parent::getConfiguration(); } - public function attachResource(DrydockResource $resource) { + public function attachResource(DrydockResource $resource = null) { $this->resource = $resource; return $this; } @@ -36,10 +36,16 @@ } public function getPolicy($capability) { + if (!$this->getResource()) { + return PhabricatorPolicies::getMostOpenPolicy(); + } return $this->getResource()->getPolicy($capability); } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { + if (!$this->getResource()) { + return false; + } return $this->getResource()->hasAutomaticCapability($capability, $viewer); } Index: src/infrastructure/daemon/workers/PhabricatorWorker.php =================================================================== --- src/infrastructure/daemon/workers/PhabricatorWorker.php +++ src/infrastructure/daemon/workers/PhabricatorWorker.php @@ -85,14 +85,28 @@ } final public static function scheduleTask($task_class, $data) { + $task = id(new PhabricatorWorkerActiveTask()) + ->setTaskClass($task_class) + ->setData($data); + if (self::$runAllTasksInProcess) { + // Do the work in-process. $worker = newv($task_class, array($data)); $worker->doWork(); + + // Now, save a task row and immediately archive it so we can return an + // object with a valid ID. + $task->openTransaction(); + $task->save(); + $archived = $task->archiveTask( + PhabricatorWorkerArchiveTask::RESULT_SUCCESS, + 0); + $task->saveTransaction(); + + return $archived; } else { - return id(new PhabricatorWorkerActiveTask()) - ->setTaskClass($task_class) - ->setData($data) - ->save(); + $task->save(); + return $task; } } @@ -105,6 +119,10 @@ * @return void */ final public static function waitForTasks(array $task_ids) { + if (!$task_ids) { + return; + } + $task_table = new PhabricatorWorkerActiveTask(); $waiting = array_fuse($task_ids); @@ -149,7 +167,8 @@ foreach ($tasks as $task) { if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) { - throw new Exception("Task ".$task->getID()." failed!"); + throw new Exception( + pht("Task %d failed!", $task->getID())); } } }