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:
parent
7a9e6af008
commit
7d1f62409d
7 changed files with 130 additions and 42 deletions
|
@ -29,6 +29,8 @@ $allocator = new DrydockAllocator();
|
||||||
$allocator->setResourceType('host');
|
$allocator->setResourceType('host');
|
||||||
$lease = $allocator->allocate();
|
$lease = $allocator->allocate();
|
||||||
|
|
||||||
|
$lease->waitUntilActive();
|
||||||
|
|
||||||
$i_file = $lease->getInterface('command');
|
$i_file = $lease->getInterface('command');
|
||||||
|
|
||||||
list($stdout) = $i_file->execx('ls / ; echo -- ; uptime ; echo -- ; uname -n');
|
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',
|
'DiffusionSymbolQuery' => 'applications/diffusion/query/symbol',
|
||||||
'DiffusionView' => 'applications/diffusion/view/base',
|
'DiffusionView' => 'applications/diffusion/view/base',
|
||||||
'DrydockAllocator' => 'applications/drydock/allocator/resource',
|
'DrydockAllocator' => 'applications/drydock/allocator/resource',
|
||||||
|
'DrydockAllocatorWorker' => 'applications/drydock/allocator/worker',
|
||||||
'DrydockBlueprint' => 'applications/drydock/blueprint/base',
|
'DrydockBlueprint' => 'applications/drydock/blueprint/base',
|
||||||
'DrydockCommandInterface' => 'applications/drydock/interface/command/base',
|
'DrydockCommandInterface' => 'applications/drydock/interface/command/base',
|
||||||
'DrydockConstants' => 'applications/drydock/constants/base',
|
'DrydockConstants' => 'applications/drydock/constants/base',
|
||||||
|
@ -1059,6 +1060,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionSvnRequest' => 'DiffusionRequest',
|
'DiffusionSvnRequest' => 'DiffusionRequest',
|
||||||
'DiffusionSymbolController' => 'DiffusionController',
|
'DiffusionSymbolController' => 'DiffusionController',
|
||||||
'DiffusionView' => 'AphrontView',
|
'DiffusionView' => 'AphrontView',
|
||||||
|
'DrydockAllocatorWorker' => 'PhabricatorWorker',
|
||||||
'DrydockCommandInterface' => 'DrydockInterface',
|
'DrydockCommandInterface' => 'DrydockInterface',
|
||||||
'DrydockController' => 'PhabricatorController',
|
'DrydockController' => 'PhabricatorController',
|
||||||
'DrydockDAO' => 'PhabricatorLiskDAO',
|
'DrydockDAO' => 'PhabricatorLiskDAO',
|
||||||
|
|
|
@ -42,45 +42,15 @@ final class DrydockAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function allocate() {
|
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 = $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;
|
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/leasestatus');
|
||||||
phutil_require_module('phabricator', 'applications/drydock/constants/resourcestatus');
|
|
||||||
phutil_require_module('phabricator', 'applications/drydock/storage/lease');
|
phutil_require_module('phabricator', 'applications/drydock/storage/lease');
|
||||||
phutil_require_module('phabricator', 'applications/drydock/storage/resource');
|
phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'utils');
|
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('DrydockAllocator.php');
|
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