1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +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:
epriestley 2012-01-23 16:58:38 -08:00
parent 7a9e6af008
commit 7d1f62409d
7 changed files with 130 additions and 42 deletions

View file

@ -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');

View file

@ -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',

View file

@ -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;
}

View file

@ -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');

View file

@ -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();
}
}

View 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');

View file

@ -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;
}
}