Create start of a lib directory
This commit is contained in:
Родитель
669999efbb
Коммит
c87328a1bf
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
class BashInterpreter {
|
||||
public static function matchCommand($text, $command) {
|
||||
$command = str_replace("/", "\/", $command);
|
||||
preg_match_all("/".$command." .*[;|$|\r\n]/", $text, $matches);
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
public static function matchFlag($command, $flag) {
|
||||
$flag = str_replace("/", "\/", $flag);
|
||||
preg_match_all("/".$flag." ([a-zA-Z0-9.~\-\/]*)/", $command, $matches);
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
public static function removeFlagFromCommand($text, $full_command, $full_flag) {
|
||||
$replaced = str_replace($full_flag, "", $full_command);
|
||||
$text = str_replace($full_command, $replaced, $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
public static function addFlagToCommands($text, $command, $full_flag) {
|
||||
return str_replace($command, $command." ".$full_flag, $text);
|
||||
}
|
||||
|
||||
public static function removeFlagFromCommands($text, $command, $full_flag) {
|
||||
foreach(BashInterpreter::matchCommand($text, $command) as $match) {
|
||||
$text = BashInterpreter::removeFlagFromCommand($text, $match, $full_flag);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
public static function removeCommand($text, $full_command) {
|
||||
return str_replace($full_command, "", $text);
|
||||
}
|
||||
|
||||
public static function normalizeDir($dir) {
|
||||
$dir = str_replace("//", "/", $dir);
|
||||
$dir = str_replace("/./", "/", $dir);
|
||||
$dir = preg_replace("#^./#", "", $dir);
|
||||
$dir = str_replace("~", '$HOME', $dir);
|
||||
$dir = preg_replace("#/$#", "", $dir);
|
||||
return $dir;
|
||||
}
|
||||
|
||||
public static function sameDir($dir1, $dir2) {
|
||||
return BashInterpreter::normalizeDir($dir1) == BashInterpreter::normalizeDir($dir2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
class Mode {
|
||||
|
||||
// db: awfy_mode
|
||||
function __construct($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
function vendor() {
|
||||
$qMode = mysql_query("SELECT vendor_id
|
||||
FROM awfy_mode
|
||||
WHERE id = {$this->id}");
|
||||
$mode = mysql_fetch_object($qMode);
|
||||
return $mode->vendor_id;
|
||||
}
|
||||
|
||||
function mode() {
|
||||
$qMode = mysql_query("SELECT mode
|
||||
FROM awfy_mode
|
||||
WHERE id = {$this->id}");
|
||||
$mode = mysql_fetch_object($qMode);
|
||||
return $mode->mode;
|
||||
}
|
||||
|
||||
function id() {
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
class QueuedTask {
|
||||
|
||||
// db: control_task_queue
|
||||
function __construct($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
function setBusy() {
|
||||
mysql_query("UPDATE control_task_queue SET busy = 1 WHERE id = {$this->id}") or die(mysql_error());
|
||||
}
|
||||
|
||||
function setFinished() {
|
||||
mysql_query("DELETE FROM control_task_queue WHERE id = {$this->id}");
|
||||
}
|
||||
|
||||
function task() {
|
||||
$qTask = mysql_query("SELECT task
|
||||
FROM control_task_queue
|
||||
WHERE id = {$this->id}");
|
||||
$task = mysql_fetch_object($qTask);
|
||||
return $task->task;
|
||||
}
|
||||
|
||||
function id() {
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
require_once("QueuedTask.php");
|
||||
|
||||
class TaskQueue {
|
||||
|
||||
// db: control_task_queue
|
||||
function __construct($unit_id) {
|
||||
$this->unit_id = $unit_id;
|
||||
}
|
||||
|
||||
// Returns if there is a task still running.
|
||||
function has_active_task() {
|
||||
$qTask = mysql_query("SELECT *
|
||||
FROM control_task_queue
|
||||
WHERE control_unit_id = {$this->unit} AND busy = 1
|
||||
ORDER BY id LIMIT 1");
|
||||
return mysql_num_rows($qTask) != 0;
|
||||
}
|
||||
|
||||
function has_queued_tasks() {
|
||||
$qTask = mysql_query("SELECT *
|
||||
FROM control_task_queue
|
||||
WHERE control_unit_id = $unit and busy = 0
|
||||
ORDER BY id LIMIT 1");
|
||||
return mysql_num_rows($qTask) != 0;
|
||||
|
||||
}
|
||||
|
||||
function pop() {
|
||||
$qTask = mysql_query("SELECT id
|
||||
FROM control_task_queue
|
||||
WHERE control_unit_id = $unit and busy = 0
|
||||
ORDER BY id LIMIT 1");
|
||||
$task = mysql_fetch_object($qTask);
|
||||
|
||||
$task = QueuedTask($task->id);
|
||||
$task->setBusy();
|
||||
|
||||
return $task;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
include_once "BashInterpreter.php";
|
||||
include_once "Task.php";
|
||||
|
||||
class ManipulateTask extends Task {
|
||||
|
||||
public function update_benchmarks($new_benchmarks) {
|
||||
//Note: Impossible to add new benchmarks using this command. Only possible to prune ones.
|
||||
$old_benchmarks = $this->benchmarks();
|
||||
$removed_benchmarks = array_diff($old_benchmarks, $new_benchmarks);
|
||||
foreach($removed_benchmarks as $removed) {
|
||||
$this->task = BashInterpreter::removeFlagFromCommands($this->task, "python execute.py", "-b ".$removed);
|
||||
}
|
||||
|
||||
$this->optimize();
|
||||
}
|
||||
|
||||
public function update_configs($new_configs) {
|
||||
//Note: Impossible to add new configs using this command. Only possible to prune ones.
|
||||
$old_configs= $this->configs();
|
||||
$removed_configs = array_diff($old_configs, $new_configs);
|
||||
foreach($removed_configs as $removed) {
|
||||
$this->task = BashInterpreter::removeFlagFromCommands($this->task, "python execute.py", "-c ".$removed);
|
||||
}
|
||||
|
||||
$this->optimize();
|
||||
}
|
||||
|
||||
public function update_engines($new_engines) {
|
||||
//Note: Impossible to add new engines using this command. Only possible to prune ones.
|
||||
$old_engines = $this->engines();
|
||||
$removed_engines = array_diff($old_engines, $new_engines);
|
||||
|
||||
// Build engines
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python build.py");
|
||||
foreach ($commands as $command) {
|
||||
$source_matches = BashInterpreter::matchFlag($command, "-s");
|
||||
$engine = $this->source_rules()[$source_matches[0]];
|
||||
print_r($removed_engines);
|
||||
if (in_array($engine, $removed_engines)) {
|
||||
$this->removeBuildOrDownloadCommand($command);
|
||||
}
|
||||
}
|
||||
|
||||
$this->optimize();
|
||||
}
|
||||
|
||||
public function update_modes($modes) {
|
||||
$engines = [];
|
||||
$configs = [];
|
||||
$mode_rules = array_flip($this->mode_rules());
|
||||
|
||||
foreach ($modes as $mode) {
|
||||
$rule = $mode_rules[$mode];
|
||||
$rule = split(",", $rule);
|
||||
$engines[] = $rule[0];
|
||||
$configs[] = $rule[1];
|
||||
}
|
||||
|
||||
$this->update_engines($engines);
|
||||
$this->update_configs($configs);
|
||||
}
|
||||
|
||||
public function setTipRevision() {
|
||||
$this->removeRevisionInfo();
|
||||
}
|
||||
|
||||
public function setRevision($new_revision) {
|
||||
$this->removeRevisionInfo();
|
||||
$this->task = BashInterpreter::addFlagToCommands($this->task, "python build.py", "-r ".$new_revision);
|
||||
}
|
||||
|
||||
private function removeRevisionInfo() {
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python download.py");
|
||||
if (count($commands) != 0)
|
||||
throw new Exception("Not yet supported to specify revision for downloaded builds.");
|
||||
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python build.py");
|
||||
foreach ($commands as $command) {
|
||||
$revision_matches = BashInterpreter::matchFlag($command, "-r");
|
||||
for ($revision_matches as $revision) {
|
||||
$this->task = BashInterpreter::removeFlagFromCommand($this->task, $command, "-r ".$revision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function removeBuildOrDownloadCommand($command) {
|
||||
$output_matches = BashInterpreter::matchFlag($command, "-o");
|
||||
$this->task = BashInterpreter::removeCommand($this->task, $command);
|
||||
if (count($output_matches) == 0) {
|
||||
// If there was no output dir specified, remove all executes where no engine dir is given.
|
||||
// or where the default 'output' dir is specified.
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python execute.py");
|
||||
foreach ($commands as $command) {
|
||||
$engine_matches = BashInterpreter::matchFlag($command, "-e");
|
||||
if (count($engine_matches) == 0) {
|
||||
$this->task = BashInterpreter::removeCommand($this->task, $command);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($engine_matches as $engineDir) {
|
||||
if (BashInterpreter::sameDir($engineDir, "output")) {
|
||||
$this->task = BashInterpreter::removeFlagFromCommand($this->task, $command, "-e ".$engineDir);
|
||||
if (count($engine_matches) == 1)
|
||||
$this->task = BashInterpreter::removeCommand($this->task, $command);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$outputDir = $output_matches[0];
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python execute.py");
|
||||
foreach ($commands as $command) {
|
||||
$engine_matches = BashInterpreter::matchFlag($command, "-e");
|
||||
foreach ($engine_matches as $engineDir) {
|
||||
if (BashInterpreter::sameDir($engineDir, $outputDir)) {
|
||||
$this->task = BashInterpreter::removeFlagFromCommand($this->task, $command, "-e ".$engineDir);
|
||||
if (count($engine_matches) == 1)
|
||||
$this->task = BashInterpreter::removeCommand($this->task, $command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private function optimize() {
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python execute.py");
|
||||
foreach ($commands as $command) {
|
||||
// Any execute without benchmarks don't need to get run.
|
||||
if (count(BashInterpreter::matchFlag($command, "-b")) == 0)
|
||||
$this->task = BashInterpreter::removeCommand($this->task, $command);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
require_once("ManipulateTask.php");
|
||||
require_once("DB/Mode.php");
|
||||
|
||||
class RetriggerController {
|
||||
|
||||
public function __construct() {
|
||||
$this->tasks = [];
|
||||
$this->unit_id = 0;
|
||||
}
|
||||
|
||||
public static function fromUnit($unit_id) {
|
||||
$retrigger = new RetriggerController();
|
||||
$retrigger->unit_id = $unit_id;
|
||||
|
||||
$qTask = mysql_query("SELECT * FROM control_tasks WHERE control_unit_id = $unit_id");
|
||||
while ($task = mysql_fetch_object($qTask)) {
|
||||
$task = new ManipulateTask($task);
|
||||
$retrigger->tasks[] = $task;
|
||||
}
|
||||
return $retrigger;
|
||||
}
|
||||
|
||||
public static function fromMachine($machine, $mode_id = 0) {
|
||||
$retrigger = new RetriggerController();
|
||||
$mode = new Mode($mode_id);
|
||||
|
||||
$qTask = mysql_query("SELECT * FROM control_tasks WHERE machine_id = $machine");
|
||||
while ($task = mysql_fetch_object($qTask)) {
|
||||
if (!($mode_id == 0 || $task->mode_id == 0 || $task->mode_id == $mode_id))
|
||||
continue;
|
||||
|
||||
$task = new ManipulateTask($task);
|
||||
if ($mode_id != 0)
|
||||
$task->update_modes($mode->mode());
|
||||
|
||||
$retrigger->tasks[] = $task;
|
||||
|
||||
if ($this->unit_id != 0 && $this->unit_id != $task->control_unit_id)
|
||||
throw new Exception("Only one machine allowed.");
|
||||
|
||||
$this->unit_id = $task->control_unit_id;
|
||||
}
|
||||
return $retrigger;
|
||||
}
|
||||
|
||||
public function setRevision($revision) {
|
||||
foreach ($this->tasks as $task) {
|
||||
$task->setRevision($revision);
|
||||
}
|
||||
}
|
||||
|
||||
public function enqueue() {
|
||||
if ($this->unit_id == 0)
|
||||
throw new Exception("No control_unit specified.");
|
||||
|
||||
foreach ($this->tasks as $task) {
|
||||
mysql_query("INSERT INTO control_task_queue
|
||||
(control_unit_id, task)
|
||||
VALUES ({$this->unit_id}, '".mysql_escape_string($task)."')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
class Task {
|
||||
|
||||
// The build function contains the 'source' it needs to fetch
|
||||
// the code from. We need to know which source is which engine.
|
||||
// This makes the transition from source to engine.
|
||||
// Note: an engine can have multiple sources.
|
||||
public function source_rules() {
|
||||
return [
|
||||
"mozilla" => "firefox",
|
||||
"v8" => "chrome",
|
||||
"webkit" => "webkit"
|
||||
];
|
||||
}
|
||||
|
||||
// The execute function looks at engine+config to decide which
|
||||
// mode it should send this data to. These contain the default rules.
|
||||
// Though it is possible to add some extra rules in the task
|
||||
// itself. These are not accounted for (TODO).
|
||||
public function mode_rules() {
|
||||
return [
|
||||
"firefox,default" => "jmim",
|
||||
"firefox,noasmjs" => "noasmjs",
|
||||
"firefox,unboxedobjects" => "unboxedobjects",
|
||||
"firefox,testbedregalloc" => "testbed",
|
||||
"chrome,default" => "v8",
|
||||
"chrome,turbofan" => "v8-turbofan",
|
||||
"webkit,default" => "jsc",
|
||||
"native,default" => "clang",
|
||||
"servo,default" => "servo"
|
||||
];
|
||||
}
|
||||
|
||||
public function __construct($task) {
|
||||
$this->task = $task;
|
||||
}
|
||||
|
||||
public function task() {
|
||||
return $this->task;
|
||||
}
|
||||
|
||||
public function configs() {
|
||||
$configs = [];
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python execute.py");
|
||||
foreach ($commands as $command) {
|
||||
$config_matches = BashInterpreter::matchFlag($command, "-c");
|
||||
foreach ($config_matches as $match) {
|
||||
$configs[] = $match;
|
||||
}
|
||||
}
|
||||
return array_unique($configs);
|
||||
}
|
||||
|
||||
public function engines() {
|
||||
$engines = [];
|
||||
|
||||
// Fetch all engines that have been build.
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python build.py");
|
||||
foreach ($commands as $command) {
|
||||
$source_matches = BashInterpreter::matchFlag($command, "-s");
|
||||
if (count($source_matches) != 1)
|
||||
throw new Error("Expected one match.");
|
||||
|
||||
$engines[] = $this->source_rules()[$source_matches[0]];
|
||||
}
|
||||
|
||||
// Fetch all engines that have been downloaded.
|
||||
// TODO.
|
||||
return array_unique($engines);
|
||||
}
|
||||
|
||||
public function modes() {
|
||||
$configs = $this->configs();
|
||||
$engines = $this->engines();
|
||||
$mode_rules = $this->mode_rules();
|
||||
|
||||
$modes = [];
|
||||
foreach ($configs as $config) {
|
||||
foreach ($engines as $engine) {
|
||||
$rule = $engine.",".$config;
|
||||
if (isset($mode_rules[$rule])) {
|
||||
$modes[] = $mode_rules[$rule];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $modes;
|
||||
}
|
||||
|
||||
public function benchmarks() {
|
||||
$configs = [];
|
||||
$commands = BashInterpreter::matchCommand($this->task, "python execute.py");
|
||||
foreach ($commands as $command) {
|
||||
$config_matches = BashInterpreter::matchFlag($command, "-b");
|
||||
foreach ($config_matches as $match) {
|
||||
$configs[] = $match;
|
||||
}
|
||||
}
|
||||
return array_unique($configs);
|
||||
}
|
||||
}
|
|
@ -5,48 +5,36 @@
|
|||
|
||||
require_once("internals.php");
|
||||
|
||||
require_once("lib/RetriggerController.php");
|
||||
require_once("lib/DB/TaskQueue.php");
|
||||
require_once("lib/DB/QueuedTask.php");
|
||||
|
||||
init_database();
|
||||
|
||||
if (isset($_GET["unit"]) && is_numeric($_GET["unit"])) {
|
||||
$unit = (int)$_GET["unit"];
|
||||
if ($unit = GET_int("unit")) {
|
||||
|
||||
$qTask = mysql_query("SELECT *
|
||||
FROM control_task_queue
|
||||
WHERE control_unit_id = $unit AND busy = 1
|
||||
ORDER BY id LIMIT 1");
|
||||
if (mysql_num_rows($qTask) != 0) {
|
||||
$queue = new TaskQueue($unit);
|
||||
if ($queue->has_active_task())
|
||||
slack("requesting new task, while old task is still running!");
|
||||
|
||||
if (!$queue->has_queued_tasks())
|
||||
$retrigger = RetriggerController::fromUnit($unit);
|
||||
$retrigger->enqueue();
|
||||
}
|
||||
|
||||
$task = $queue->pop();
|
||||
|
||||
$qTask = mysql_query("SELECT *
|
||||
FROM control_task_queue
|
||||
WHERE control_unit_id = $unit and busy = 0
|
||||
ORDER BY id LIMIT 1");
|
||||
if (mysql_num_rows($qTask) == 0) {
|
||||
$qTask = mysql_query("SELECT task FROM control_tasks WHERE control_unit_id = $unit");
|
||||
while ($task = mysql_fetch_object($qTask)) {
|
||||
mysql_query("INSERT INTO control_task_queue
|
||||
(control_unit_id, task)
|
||||
VALUES ($unit, '".mysql_escape_string($tasks->task)."')");
|
||||
}
|
||||
}
|
||||
|
||||
$qTask = mysql_query("SELECT *
|
||||
FROM control_task_queue
|
||||
WHERE control_unit_id = $unit and busy = 0
|
||||
ORDER BY id LIMIT 1");
|
||||
$task = mysql_fetch_object($qTask);
|
||||
echo json_encode(Array("task" => $task->task,
|
||||
"id" => $task->id));
|
||||
|
||||
mysql_query("UPDATE control_task_queue SET busy = 1 WHERE id = ".$task->id);
|
||||
echo json_encode([
|
||||
"task" => $task->task(),
|
||||
"id" => $task->id()
|
||||
]);
|
||||
|
||||
die();
|
||||
|
||||
} else if (isset($_GET["finish"]) && is_numeric($_GET["finish"])) {
|
||||
$task_id = $_GET["finish"];
|
||||
mysql_query("DELETE FROM control_task_queue WHERE id = ".$task_id);
|
||||
} else if ($task_id = GET_int("finish")) {
|
||||
|
||||
$task = QueuedTask($task_id);
|
||||
$task->setFinished();
|
||||
|
||||
die();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче