Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/sql/patches/031.workerrace.sql b/resources/sql/patches/031.workerrace.sql
new file mode 100644
index 0000000000..e643068f23
--- /dev/null
+++ b/resources/sql/patches/031.workerrace.sql
@@ -0,0 +1,13 @@
+ALTER TABLE phabricator_worker.worker_task
+ ADD dataID int unsigned;
+
+ALTER TABLE phabricator_worker.worker_task
+ ADD UNIQUE KEY (dataID);
+
+UPDATE phabricator_worker.worker_task t,
+ phabricator_worker.worker_taskdata d
+ SET t.dataID = d.id
+ WHERE d.taskID = t.id;
+
+ALTER TABLE phabricator_worker.worker_taskdata
+ DROP taskID;
diff --git a/src/applications/daemon/controller/workertaskdetail/PhabricatorWorkerTaskDetailController.php b/src/applications/daemon/controller/workertaskdetail/PhabricatorWorkerTaskDetailController.php
index 80fadc6047..03cbfdcadc 100644
--- a/src/applications/daemon/controller/workertaskdetail/PhabricatorWorkerTaskDetailController.php
+++ b/src/applications/daemon/controller/workertaskdetail/PhabricatorWorkerTaskDetailController.php
@@ -1,95 +1,95 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorWorkerTaskDetailController
extends PhabricatorDaemonController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$task = id(new PhabricatorWorkerTask())->load($this->id);
if (!$task) {
$error_view = new AphrontErrorView();
$error_view->setTitle('No Such Task');
$error_view->appendChild(
'<p>This task may have recently completed.</p>');
$error_view->setSeverity(AphrontErrorView::SEVERITY_WARNING);
return $this->buildStandardPageResponse(
$error_view,
array(
'title' => 'Task Does Not Exist',
));
}
$data = id(new PhabricatorWorkerTaskData())->loadOneWhere(
- 'taskID = %d',
- $task->getID());
+ 'id = %d',
+ $task->getDataID());
if ($data) {
$data = json_encode($data->getData());
}
$form = id(new AphrontFormView())
->setUser($user)
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('ID')
->setValue($task->getID()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Type')
->setValue($task->getTaskClass()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Lease Owner')
->setValue($task->getLeaseOwner()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Lease Expires')
->setValue($task->getLeaseExpires() - time()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Failure Count')
->setValue($task->getFailureCount()))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Data')
->setValue($data))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/daemon/'));
$panel = new AphrontPanelView();
$panel->setHeader('Task Detail');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Task',
));
}
}
diff --git a/src/infrastructure/daemon/workers/storage/task/PhabricatorWorkerTask.php b/src/infrastructure/daemon/workers/storage/task/PhabricatorWorkerTask.php
index 9d980095db..8eaa414674 100644
--- a/src/infrastructure/daemon/workers/storage/task/PhabricatorWorkerTask.php
+++ b/src/infrastructure/daemon/workers/storage/task/PhabricatorWorkerTask.php
@@ -1,82 +1,82 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorWorkerTask extends PhabricatorWorkerDAO {
protected $taskClass;
protected $leaseOwner;
protected $leaseExpires;
protected $failureCount;
+ protected $dataID;
private $serverTime;
private $localTime;
private $data;
public function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
) + parent::getConfiguration();
}
public function setServerTime($server_time) {
$this->serverTime = $server_time;
$this->localTime = time();
return $this;
}
public function setLeaseDuration($lease_duration) {
$server_lease_expires = $this->serverTime + $lease_duration;
$this->setLeaseExpires($server_lease_expires);
return $this->save();
}
public function save() {
if ($this->leaseOwner) {
$current_server_time = $this->serverTime + (time() - $this->localTime);
if ($current_server_time >= $this->leaseExpires) {
throw new Exception("Trying to update task after lease expiration!");
}
}
$is_new = !$this->getID();
if ($is_new) {
$this->failureCount = 0;
}
- $ret = parent::save();
-
if ($is_new && $this->data) {
$data = new PhabricatorWorkerTaskData();
- $data->setTaskID($this->getID());
$data->setData($this->data);
$data->save();
+
+ $this->setDataID($data->getID());
}
- return $ret;
+ return parent::save();
}
public function setData($data) {
$this->data = $data;
return $this;
}
public function getData() {
return $this->data;
}
}
diff --git a/src/infrastructure/daemon/workers/storage/taskdata/PhabricatorWorkerTaskData.php b/src/infrastructure/daemon/workers/storage/taskdata/PhabricatorWorkerTaskData.php
index 8407e47aa7..007aea0892 100644
--- a/src/infrastructure/daemon/workers/storage/taskdata/PhabricatorWorkerTaskData.php
+++ b/src/infrastructure/daemon/workers/storage/taskdata/PhabricatorWorkerTaskData.php
@@ -1,33 +1,32 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorWorkerTaskData extends PhabricatorWorkerDAO {
- protected $taskID;
protected $data;
public function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_SERIALIZATION => array(
'data' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
}
diff --git a/src/infrastructure/daemon/workers/taskmaster/PhabricatorTaskmasterDaemon.php b/src/infrastructure/daemon/workers/taskmaster/PhabricatorTaskmasterDaemon.php
index 4a5d202312..a8cc469b8a 100644
--- a/src/infrastructure/daemon/workers/taskmaster/PhabricatorTaskmasterDaemon.php
+++ b/src/infrastructure/daemon/workers/taskmaster/PhabricatorTaskmasterDaemon.php
@@ -1,128 +1,128 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorTaskmasterDaemon extends PhabricatorDaemon {
public function run() {
$lease_ownership_name = $this->getLeaseOwnershipName();
$task_table = new PhabricatorWorkerTask();
$taskdata_table = new PhabricatorWorkerTaskData();
$sleep = 0;
do {
$conn_w = $task_table->establishConnection('w');
queryfx(
$conn_w,
'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15
WHERE leaseOwner IS NULL LIMIT 1',
$task_table->getTableName(),
$lease_ownership_name);
$rows = $conn_w->getAffectedRows();
if (!$rows) {
$rows = queryfx(
$conn_w,
'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15
WHERE leaseExpires < UNIX_TIMESTAMP() LIMIT 1',
$task_table->getTableName(),
$lease_ownership_name);
$rows = $conn_w->getAffectedRows();
}
if ($rows) {
$data = queryfx_all(
$conn_w,
'SELECT task.*, taskdata.data _taskData, UNIX_TIMESTAMP() _serverTime
FROM %T task LEFT JOIN %T taskdata
- ON taskdata.taskID = task.id
+ ON taskdata.id = task.dataID
WHERE leaseOwner = %s AND leaseExpires > UNIX_TIMESTAMP()
LIMIT 1',
$task_table->getTableName(),
$taskdata_table->getTableName(),
$lease_ownership_name);
$tasks = $task_table->loadAllFromArray($data);
$tasks = mpull($tasks, null, 'getID');
$task_data = array();
foreach ($data as $row) {
$tasks[$row['id']]->setServerTime($row['_serverTime']);
if ($row['_taskData']) {
$task_data[$row['id']] = json_decode($row['_taskData'], true);
} else {
$task_data[$row['id']] = null;
}
}
foreach ($tasks as $task) {
// TODO: We should detect if we acquired a task with an expired lease
// and log about it / bump up failure count.
// TODO: We should detect if we acquired a task with an excessive
// failure count and fail it permanently.
$data = idx($task_data, $task->getID());
$class = $task->getTaskClass();
try {
PhutilSymbolLoader::loadClass($class);
if (!is_subclass_of($class, 'PhabricatorWorker')) {
throw new Exception(
"Task class '{$class}' does not extend PhabricatorWorker.");
}
$worker = newv($class, array($data));
$lease = $worker->getRequiredLeaseTime();
if ($lease !== null) {
$task->setLeaseDuration($lease);
}
$worker->executeTask();
$task->delete();
if ($data !== null) {
queryfx(
$conn_w,
- 'DELETE FROM %T WHERE taskID = %d',
+ 'DELETE FROM %T WHERE id = %d',
$taskdata_table->getTableName(),
- $task->getID());
+ $task->getDataID());
}
} catch (Exception $ex) {
$task->setFailureCount($task->getFailureCount() + 1);
$task->save();
throw $ex;
}
}
$sleep = 0;
} else {
$sleep = min($sleep + 1, 30);
}
$this->sleep($sleep);
} while (true);
}
private function getLeaseOwnershipName() {
static $name = null;
if ($name === null) {
$name = getmypid().':'.time().':'.php_uname('n');
}
return $name;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Dec 1, 12:49 AM (20 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
430060
Default Alt Text
(12 KB)

Event Timeline