mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Move resource allocation to task queue
Summary: Run the actual resource allocation for Drydock out-of-process via the task queue. Test Plan: Ran "drydock_control.php", saw it insert a task and wait for task completion. Ran "phd debug taskmaster" and saw it run the task. Reviewers: btrahan, jungejason Reviewed By: btrahan CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D1470
This commit is contained in:
parent
7a9e6af008
commit
7d1f62409d
7 changed files with 130 additions and 42 deletions
|
@ -29,6 +29,8 @@ $allocator = new DrydockAllocator();
|
|||
$allocator->setResourceType('host');
|
||||
$lease = $allocator->allocate();
|
||||
|
||||
$lease->waitUntilActive();
|
||||
|
||||
$i_file = $lease->getInterface('command');
|
||||
|
||||
list($stdout) = $i_file->execx('ls / ; echo -- ; uptime ; echo -- ; uname -n');
|
||||
|
|
|
@ -312,6 +312,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionSymbolQuery' => 'applications/diffusion/query/symbol',
|
||||
'DiffusionView' => 'applications/diffusion/view/base',
|
||||
'DrydockAllocator' => 'applications/drydock/allocator/resource',
|
||||
'DrydockAllocatorWorker' => 'applications/drydock/allocator/worker',
|
||||
'DrydockBlueprint' => 'applications/drydock/blueprint/base',
|
||||
'DrydockCommandInterface' => 'applications/drydock/interface/command/base',
|
||||
'DrydockConstants' => 'applications/drydock/constants/base',
|
||||
|
@ -1059,6 +1060,7 @@ phutil_register_library_map(array(
|
|||
'DiffusionSvnRequest' => 'DiffusionRequest',
|
||||
'DiffusionSymbolController' => 'DiffusionController',
|
||||
'DiffusionView' => 'AphrontView',
|
||||
'DrydockAllocatorWorker' => 'PhabricatorWorker',
|
||||
'DrydockCommandInterface' => 'DrydockInterface',
|
||||
'DrydockController' => 'PhabricatorController',
|
||||
'DrydockDAO' => 'PhabricatorLiskDAO',
|
||||
|
|
|
@ -42,45 +42,15 @@ final class DrydockAllocator {
|
|||
}
|
||||
|
||||
public function allocate() {
|
||||
$type = $this->getResourceType();
|
||||
|
||||
$candidates = id(new DrydockResource())->loadAllWhere(
|
||||
'type = %s AND status = %s',
|
||||
$type,
|
||||
DrydockResourceStatus::STATUS_OPEN);
|
||||
|
||||
if ($candidates) {
|
||||
shuffle($candidates);
|
||||
$resource = head($candidates);
|
||||
} else {
|
||||
$blueprints = DrydockBlueprint::getAllBlueprintsForResource($type);
|
||||
|
||||
foreach ($blueprints as $key => $blueprint) {
|
||||
if (!$blueprint->canAllocateResources()) {
|
||||
unset($blueprints[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$blueprints) {
|
||||
throw new Exception(
|
||||
"There are no valid existing '{$type}' resources, and no valid ".
|
||||
"blueprints to build new ones.");
|
||||
}
|
||||
|
||||
// TODO: Rank intelligently.
|
||||
shuffle($blueprints);
|
||||
|
||||
$blueprint = head($blueprints);
|
||||
$resource = $blueprint->allocateResource();
|
||||
}
|
||||
|
||||
$lease = $this->getPendingLease();
|
||||
$lease->setResourceID($resource->getID());
|
||||
$lease->setStatus(DrydockLeaseStatus::STATUS_ACTIVE);
|
||||
$lease->save();
|
||||
|
||||
$lease->attachResource($resource);
|
||||
$task = new PhabricatorWorkerTask();
|
||||
$task->setTaskClass('DrydockAllocatorWorker');
|
||||
$task->setData(array(
|
||||
'type' => $this->getResourceType(),
|
||||
'lease' => $lease->getID(),
|
||||
));
|
||||
$task->save();
|
||||
|
||||
return $lease;
|
||||
}
|
||||
|
|
|
@ -6,13 +6,9 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/drydock/blueprint/base');
|
||||
phutil_require_module('phabricator', 'applications/drydock/constants/leasestatus');
|
||||
phutil_require_module('phabricator', 'applications/drydock/constants/resourcestatus');
|
||||
phutil_require_module('phabricator', 'applications/drydock/storage/lease');
|
||||
phutil_require_module('phabricator', 'applications/drydock/storage/resource');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
|
||||
|
||||
|
||||
phutil_require_source('DrydockAllocator.php');
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
final class DrydockAllocatorWorker extends PhabricatorWorker {
|
||||
|
||||
protected function doWork() {
|
||||
$data = $this->getTaskData();
|
||||
|
||||
$lease = id(new DrydockLease())->loadOneWhere(
|
||||
'id = %d',
|
||||
$data['lease']);
|
||||
if (!$lease) {
|
||||
return;
|
||||
}
|
||||
|
||||
$type = $data['type'];
|
||||
|
||||
$candidates = id(new DrydockResource())->loadAllWhere(
|
||||
'type = %s AND status = %s',
|
||||
$type,
|
||||
DrydockResourceStatus::STATUS_OPEN);
|
||||
|
||||
if ($candidates) {
|
||||
shuffle($candidates);
|
||||
$resource = head($candidates);
|
||||
} else {
|
||||
$blueprints = DrydockBlueprint::getAllBlueprintsForResource($type);
|
||||
|
||||
foreach ($blueprints as $key => $blueprint) {
|
||||
if (!$blueprint->canAllocateResources()) {
|
||||
unset($blueprints[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$blueprints) {
|
||||
$lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN);
|
||||
$lease->save();
|
||||
|
||||
/* TODO
|
||||
$lease->updateLog(
|
||||
"There are no resources of type '{$type}' available, and no ".
|
||||
"blueprints which can allocate new ones.");
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Rank intelligently.
|
||||
shuffle($blueprints);
|
||||
|
||||
$blueprint = head($blueprints);
|
||||
$resource = $blueprint->allocateResource();
|
||||
}
|
||||
|
||||
$lease->setResourceID($resource->getID());
|
||||
$lease->setStatus(DrydockLeaseStatus::STATUS_ACTIVE);
|
||||
$lease->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
19
src/applications/drydock/allocator/worker/__init__.php
Normal file
19
src/applications/drydock/allocator/worker/__init__.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/drydock/blueprint/base');
|
||||
phutil_require_module('phabricator', 'applications/drydock/constants/leasestatus');
|
||||
phutil_require_module('phabricator', 'applications/drydock/constants/resourcestatus');
|
||||
phutil_require_module('phabricator', 'applications/drydock/storage/lease');
|
||||
phutil_require_module('phabricator', 'applications/drydock/storage/resource');
|
||||
phutil_require_module('phabricator', 'infrastructure/daemon/workers/worker');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('DrydockAllocatorWorker.php');
|
|
@ -86,4 +86,25 @@ class DrydockLease extends DrydockDAO {
|
|||
}
|
||||
}
|
||||
|
||||
public function waitUntilActive() {
|
||||
while (true) {
|
||||
switch ($this->status) {
|
||||
case DrydockLeaseStatus::STATUS_ACTIVE:
|
||||
break 2;
|
||||
case DrydockLeaseStatus::STATUS_RELEASED:
|
||||
case DrydockLeaseStatus::STATUS_EXPIRED:
|
||||
case DrydockLeaseStatus::STATUS_BROKEN:
|
||||
throw new Exception("Lease will never become active!");
|
||||
case DrydockLeaseStatus::STATUS_PENDING:
|
||||
break;
|
||||
}
|
||||
sleep(2);
|
||||
$this->reload();
|
||||
}
|
||||
|
||||
$this->attachResource($this->loadResource());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue