mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Allow worker tasks to have priorities
Summary: Fixes T5336. Currently, `PhabricatorWorkerLeaseQuery` is basically FIFO. It makes more sense for the queue to be a priority-queue, and to assign higher priorities to alerts (email and SMS). Test Plan: Created dummy tasks in the queue (with different priorities). Verified that the priority field was set correctly in the DB and that the priority was shown on the `/daemon/` page. Started a `PhabricatorTaskmasterDaemon` and verified that the higher priority tasks were executed before lower priority tasks. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: epriestley, Korvin Maniphest Tasks: T5336 Differential Revision: https://secure.phabricator.com/D9871
This commit is contained in:
parent
66a3abe058
commit
9a679bf374
15 changed files with 131 additions and 91 deletions
11
resources/sql/autopatches/20140711.workerpriority.sql
Normal file
11
resources/sql/autopatches/20140711.workerpriority.sql
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_worker.worker_activetask
|
||||||
|
ADD COLUMN priority int unsigned NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_worker.worker_activetask
|
||||||
|
ADD KEY (leaseOwner, priority, id);
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_worker.worker_archivetask
|
||||||
|
ADD COLUMN priority int unsigned NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_worker.worker_archivetask
|
||||||
|
ADD KEY (leaseOwner, priority, id);
|
|
@ -267,7 +267,10 @@ foreach ($commits as $commit) {
|
||||||
|
|
||||||
if ($all_from_repo && !$force_local) {
|
if ($all_from_repo && !$force_local) {
|
||||||
foreach ($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
PhabricatorWorker::scheduleTask($class, $spec);
|
PhabricatorWorker::scheduleTask(
|
||||||
|
$class,
|
||||||
|
$spec,
|
||||||
|
PhabricatorWorker::PRIORITY_IMPORT);
|
||||||
|
|
||||||
$commit_name = 'r'.$callsign.$commit->getCommitIdentifier();
|
$commit_name = 'r'.$callsign.$commit->getCommitIdentifier();
|
||||||
echo " Queued '{$class}' for commit '{$commit_name}'.\n";
|
echo " Queued '{$class}' for commit '{$commit_name}'.\n";
|
||||||
|
|
|
@ -136,6 +136,7 @@ final class PhabricatorDaemonConsoleController
|
||||||
$task->getTaskClass(),
|
$task->getTaskClass(),
|
||||||
$task->getLeaseOwner(),
|
$task->getLeaseOwner(),
|
||||||
$task->getLeaseExpires() - time(),
|
$task->getLeaseExpires() - time(),
|
||||||
|
$task->getPriority(),
|
||||||
$task->getFailureCount(),
|
$task->getFailureCount(),
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
'a',
|
'a',
|
||||||
|
@ -158,6 +159,7 @@ final class PhabricatorDaemonConsoleController
|
||||||
pht('Class'),
|
pht('Class'),
|
||||||
pht('Owner'),
|
pht('Owner'),
|
||||||
pht('Expires'),
|
pht('Expires'),
|
||||||
|
pht('Priority'),
|
||||||
pht('Failures'),
|
pht('Failures'),
|
||||||
'',
|
'',
|
||||||
));
|
));
|
||||||
|
@ -168,6 +170,7 @@ final class PhabricatorDaemonConsoleController
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'n',
|
'n',
|
||||||
|
'n',
|
||||||
'action',
|
'action',
|
||||||
));
|
));
|
||||||
$leased_table->setNoDataString(pht('No tasks are leased by workers.'));
|
$leased_table->setNoDataString(pht('No tasks are leased by workers.'));
|
||||||
|
|
|
@ -187,7 +187,8 @@ final class DiffusionCommitHookEngine extends Phobject {
|
||||||
'eventPHID' => $event->getPHID(),
|
'eventPHID' => $event->getPHID(),
|
||||||
'emailPHIDs' => array_values($this->emailPHIDs),
|
'emailPHIDs' => array_values($this->emailPHIDs),
|
||||||
'info' => $this->loadCommitInfoForWorker($all_updates),
|
'info' => $this->loadCommitInfoForWorker($all_updates),
|
||||||
));
|
),
|
||||||
|
PhabricatorWorker::PRIORITY_ALERTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -49,7 +49,8 @@ final class PhabricatorMailManagementResendWorkflow
|
||||||
|
|
||||||
$mailer_task = PhabricatorWorker::scheduleTask(
|
$mailer_task = PhabricatorWorker::scheduleTask(
|
||||||
'PhabricatorMetaMTAWorker',
|
'PhabricatorMetaMTAWorker',
|
||||||
$message->getID());
|
$message->getID(),
|
||||||
|
PhabricatorWorker::PRIORITY_ALERTS);
|
||||||
|
|
||||||
$console->writeOut(
|
$console->writeOut(
|
||||||
"Queued message #%d for resend.\n",
|
"Queued message #%d for resend.\n",
|
||||||
|
|
|
@ -300,7 +300,8 @@ final class PhabricatorMetaMTAMail extends PhabricatorMetaMTADAO {
|
||||||
// Queue a task to send this mail.
|
// Queue a task to send this mail.
|
||||||
$mailer_task = PhabricatorWorker::scheduleTask(
|
$mailer_task = PhabricatorWorker::scheduleTask(
|
||||||
'PhabricatorMetaMTAWorker',
|
'PhabricatorMetaMTAWorker',
|
||||||
$this->getID());
|
$this->getID(),
|
||||||
|
PhabricatorWorker::PRIORITY_ALERTS);
|
||||||
|
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ final class PhabricatorSearchIndexer {
|
||||||
'PhabricatorSearchWorker',
|
'PhabricatorSearchWorker',
|
||||||
array(
|
array(
|
||||||
'documentPHID' => $phid,
|
'documentPHID' => $phid,
|
||||||
));
|
),
|
||||||
|
PhabricatorWorker::PRIORITY_IMPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function indexDocumentByPHID($phid) {
|
public function indexDocumentByPHID($phid) {
|
||||||
|
|
|
@ -9,6 +9,11 @@ abstract class PhabricatorWorker {
|
||||||
private static $runAllTasksInProcess = false;
|
private static $runAllTasksInProcess = false;
|
||||||
private $queuedTasks = array();
|
private $queuedTasks = array();
|
||||||
|
|
||||||
|
const PRIORITY_ALERTS = 4000;
|
||||||
|
const PRIORITY_DEFAULT = 3000;
|
||||||
|
const PRIORITY_BULK = 2000;
|
||||||
|
const PRIORITY_IMPORT = 1000;
|
||||||
|
|
||||||
|
|
||||||
/* -( Configuring Retries and Failures )----------------------------------- */
|
/* -( Configuring Retries and Failures )----------------------------------- */
|
||||||
|
|
||||||
|
@ -32,8 +37,8 @@ abstract class PhabricatorWorker {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the maximum number of times this task may be retried before it
|
* Return the maximum number of times this task may be retried before it is
|
||||||
* is considered permanently failed. By default, tasks retry indefinitely. You
|
* considered permanently failed. By default, tasks retry indefinitely. You
|
||||||
* can throw a @{class:PhabricatorWorkerPermanentFailureException} to cause an
|
* can throw a @{class:PhabricatorWorkerPermanentFailureException} to cause an
|
||||||
* immediate permanent failure.
|
* immediate permanent failure.
|
||||||
*
|
*
|
||||||
|
@ -53,11 +58,11 @@ abstract class PhabricatorWorker {
|
||||||
* a short default retry period (currently 60 seconds).
|
* a short default retry period (currently 60 seconds).
|
||||||
*
|
*
|
||||||
* @param PhabricatorWorkerTask The task itself. This object is probably
|
* @param PhabricatorWorkerTask The task itself. This object is probably
|
||||||
* useful mostly to examine the failure
|
* useful mostly to examine the failure count
|
||||||
* count if you want to implement staggered
|
* if you want to implement staggered retries,
|
||||||
* retries, or to examine the execution
|
* or to examine the execution exception if
|
||||||
* exception if you want to react to
|
* you want to react to different failures in
|
||||||
* different failures in different ways.
|
* different ways.
|
||||||
* @return int|null Number of seconds to wait between retries,
|
* @return int|null Number of seconds to wait between retries,
|
||||||
* or null for a default retry period
|
* or null for a default retry period
|
||||||
* (currently 60 seconds).
|
* (currently 60 seconds).
|
||||||
|
@ -70,7 +75,6 @@ abstract class PhabricatorWorker {
|
||||||
|
|
||||||
abstract protected function doWork();
|
abstract protected function doWork();
|
||||||
|
|
||||||
|
|
||||||
final public function __construct($data) {
|
final public function __construct($data) {
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
@ -83,10 +87,19 @@ abstract class PhabricatorWorker {
|
||||||
$this->doWork();
|
$this->doWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
final public static function scheduleTask($task_class, $data) {
|
final public static function scheduleTask(
|
||||||
|
$task_class,
|
||||||
|
$data,
|
||||||
|
$priority = null) {
|
||||||
|
|
||||||
|
if ($priority === null) {
|
||||||
|
$priority = self::PRIORITY_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
$task = id(new PhabricatorWorkerActiveTask())
|
$task = id(new PhabricatorWorkerActiveTask())
|
||||||
->setTaskClass($task_class)
|
->setTaskClass($task_class)
|
||||||
->setData($data);
|
->setData($data)
|
||||||
|
->setPriority($priority);
|
||||||
|
|
||||||
if (self::$runAllTasksInProcess) {
|
if (self::$runAllTasksInProcess) {
|
||||||
// Do the work in-process.
|
// Do the work in-process.
|
||||||
|
@ -96,8 +109,8 @@ abstract class PhabricatorWorker {
|
||||||
try {
|
try {
|
||||||
$worker->doWork();
|
$worker->doWork();
|
||||||
foreach ($worker->getQueuedTasks() as $queued_task) {
|
foreach ($worker->getQueuedTasks() as $queued_task) {
|
||||||
list($queued_class, $queued_data) = $queued_task;
|
list($queued_class, $queued_data, $queued_priority) = $queued_task;
|
||||||
self::scheduleTask($queued_class, $queued_data);
|
self::scheduleTask($queued_class, $queued_data, $queued_priority);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} catch (PhabricatorWorkerYieldException $ex) {
|
} catch (PhabricatorWorkerYieldException $ex) {
|
||||||
|
@ -106,7 +119,6 @@ abstract class PhabricatorWorker {
|
||||||
'In-process task "%s" yielded for %s seconds, sleeping...',
|
'In-process task "%s" yielded for %s seconds, sleeping...',
|
||||||
$task_class,
|
$task_class,
|
||||||
$ex->getDuration()));
|
$ex->getDuration()));
|
||||||
|
|
||||||
sleep($ex->getDuration());
|
sleep($ex->getDuration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,8 +196,7 @@ abstract class PhabricatorWorker {
|
||||||
|
|
||||||
foreach ($tasks as $task) {
|
foreach ($tasks as $task) {
|
||||||
if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) {
|
if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) {
|
||||||
throw new Exception(
|
throw new Exception(pht('Task %d failed!', $task->getID()));
|
||||||
pht('Task %d failed!', $task->getID()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +215,7 @@ abstract class PhabricatorWorker {
|
||||||
self::$runAllTasksInProcess = $all;
|
self::$runAllTasksInProcess = $all;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function log($pattern /* $args */) {
|
final protected function log($pattern /* , ... */) {
|
||||||
$console = PhutilConsole::getConsole();
|
$console = PhutilConsole::getConsole();
|
||||||
$argv = func_get_args();
|
$argv = func_get_args();
|
||||||
call_user_func_array(array($console, 'writeLog'), $argv);
|
call_user_func_array(array($console, 'writeLog'), $argv);
|
||||||
|
@ -219,10 +230,11 @@ abstract class PhabricatorWorker {
|
||||||
*
|
*
|
||||||
* @param string Task class to queue.
|
* @param string Task class to queue.
|
||||||
* @param array Data for the followup task.
|
* @param array Data for the followup task.
|
||||||
|
* @param int|null Priority for the followup task.
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
protected function queueTask($class, array $data) {
|
final protected function queueTask($class, array $data, $priority = null) {
|
||||||
$this->queuedTasks[] = array($class, $data);
|
$this->queuedTasks[] = array($class, $data, $priority);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,9 +242,9 @@ abstract class PhabricatorWorker {
|
||||||
/**
|
/**
|
||||||
* Get tasks queued as followups by @{method:queueTask}.
|
* Get tasks queued as followups by @{method:queueTask}.
|
||||||
*
|
*
|
||||||
* @return list<pair<string, wild>> Queued task specifications.
|
* @return list<tuple<string, wild, int|null>> Queued task specifications.
|
||||||
*/
|
*/
|
||||||
public function getQueuedTasks() {
|
final public function getQueuedTasks() {
|
||||||
return $this->queuedTasks;
|
return $this->queuedTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,7 @@ final class PhabricatorTestWorker extends PhabricatorWorker {
|
||||||
protected function doWork() {
|
protected function doWork() {
|
||||||
switch (idx($this->getTaskData(), 'doWork')) {
|
switch (idx($this->getTaskData(), 'doWork')) {
|
||||||
case 'fail-temporary':
|
case 'fail-temporary':
|
||||||
throw new Exception(
|
throw new Exception('Temporary failure!');
|
||||||
'Temporary failure!');
|
|
||||||
case 'fail-permanent':
|
case 'fail-permanent':
|
||||||
throw new PhabricatorWorkerPermanentFailureException(
|
throw new PhabricatorWorkerPermanentFailureException(
|
||||||
'Permanent failure!');
|
'Permanent failure!');
|
||||||
|
|
|
@ -9,35 +9,30 @@ final class PhabricatorWorkerTestCase extends PhabricatorTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLeaseTask() {
|
public function testLeaseTask() {
|
||||||
// Leasing should work.
|
|
||||||
|
|
||||||
$task = $this->scheduleTask();
|
$task = $this->scheduleTask();
|
||||||
|
$this->expectNextLease($task, 'Leasing should work.');
|
||||||
$this->expectNextLease($task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMultipleLease() {
|
public function testMultipleLease() {
|
||||||
// We should not be able to lease a task multiple times.
|
|
||||||
|
|
||||||
$task = $this->scheduleTask();
|
$task = $this->scheduleTask();
|
||||||
|
|
||||||
$this->expectNextLease($task);
|
$this->expectNextLease($task);
|
||||||
$this->expectNextLease(null);
|
$this->expectNextLease(
|
||||||
|
null,
|
||||||
|
'We should not be able to lease a task multiple times.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testOldestFirst() {
|
public function testOldestFirst() {
|
||||||
// Older tasks should lease first, all else being equal.
|
|
||||||
|
|
||||||
$task1 = $this->scheduleTask();
|
$task1 = $this->scheduleTask();
|
||||||
$task2 = $this->scheduleTask();
|
$task2 = $this->scheduleTask();
|
||||||
|
|
||||||
$this->expectNextLease($task1);
|
$this->expectNextLease(
|
||||||
|
$task1,
|
||||||
|
'Older tasks should lease first, all else being equal.');
|
||||||
$this->expectNextLease($task2);
|
$this->expectNextLease($task2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNewBeforeLeased() {
|
public function testNewBeforeLeased() {
|
||||||
// Tasks not previously leased should lease before previously leased tasks.
|
|
||||||
|
|
||||||
$task1 = $this->scheduleTask();
|
$task1 = $this->scheduleTask();
|
||||||
$task2 = $this->scheduleTask();
|
$task2 = $this->scheduleTask();
|
||||||
|
|
||||||
|
@ -45,7 +40,10 @@ final class PhabricatorWorkerTestCase extends PhabricatorTestCase {
|
||||||
$task1->setLeaseExpires(time() - 100000);
|
$task1->setLeaseExpires(time() - 100000);
|
||||||
$task1->forceSaveWithoutLease();
|
$task1->forceSaveWithoutLease();
|
||||||
|
|
||||||
$this->expectNextLease($task2);
|
$this->expectNextLease(
|
||||||
|
$task2,
|
||||||
|
'Tasks not previously leased should lease before previously '.
|
||||||
|
'leased tasks.');
|
||||||
$this->expectNextLease($task1);
|
$this->expectNextLease($task1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +143,6 @@ final class PhabricatorWorkerTestCase extends PhabricatorTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLeasedIsOldestFirst() {
|
public function testLeasedIsOldestFirst() {
|
||||||
// Tasks which expired earlier should lease first, all else being equal.
|
|
||||||
|
|
||||||
$task1 = $this->scheduleTask();
|
$task1 = $this->scheduleTask();
|
||||||
$task2 = $this->scheduleTask();
|
$task2 = $this->scheduleTask();
|
||||||
|
|
||||||
|
@ -158,36 +154,59 @@ final class PhabricatorWorkerTestCase extends PhabricatorTestCase {
|
||||||
$task2->setLeaseExpires(time() - 200000);
|
$task2->setLeaseExpires(time() - 200000);
|
||||||
$task2->forceSaveWithoutLease();
|
$task2->forceSaveWithoutLease();
|
||||||
|
|
||||||
$this->expectNextLease($task2);
|
$this->expectNextLease(
|
||||||
|
$task2,
|
||||||
|
'Tasks which expired earlier should lease first, all else being equal.');
|
||||||
$this->expectNextLease($task1);
|
$this->expectNextLease($task1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function expectNextLease($task) {
|
public function testLeasedIsHighestPriority() {
|
||||||
|
$task1 = $this->scheduleTask(array(), 2);
|
||||||
|
$task2 = $this->scheduleTask(array(), 1);
|
||||||
|
$task3 = $this->scheduleTask(array(), 1);
|
||||||
|
|
||||||
|
$this->expectNextLease(
|
||||||
|
$task1,
|
||||||
|
'Tasks with a higher priority should be scheduled first.');
|
||||||
|
$this->expectNextLease(
|
||||||
|
$task2,
|
||||||
|
'Tasks with the same priority should be FIFO.');
|
||||||
|
$this->expectNextLease($task3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function expectNextLease($task, $message = null) {
|
||||||
$leased = id(new PhabricatorWorkerLeaseQuery())
|
$leased = id(new PhabricatorWorkerLeaseQuery())
|
||||||
->setLimit(1)
|
->setLimit(1)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
if ($task === null) {
|
if ($task === null) {
|
||||||
$this->assertEqual(0, count($leased));
|
$this->assertEqual(0, count($leased), $message);
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
$this->assertEqual(1, count($leased));
|
$this->assertEqual(1, count($leased), $message);
|
||||||
$this->assertEqual(
|
$this->assertEqual(
|
||||||
(int)head($leased)->getID(),
|
(int)head($leased)->getID(),
|
||||||
(int)$task->getID());
|
(int)$task->getID(),
|
||||||
|
$message);
|
||||||
return head($leased);
|
return head($leased);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function scheduleAndExecuteTask(array $data = array()) {
|
private function scheduleAndExecuteTask(
|
||||||
$task = $this->scheduleTask($data);
|
array $data = array(),
|
||||||
|
$priority = null) {
|
||||||
|
|
||||||
|
$task = $this->scheduleTask($data, $priority);
|
||||||
$task = $this->expectNextLease($task);
|
$task = $this->expectNextLease($task);
|
||||||
$task = $task->executeTask();
|
$task = $task->executeTask();
|
||||||
return $task;
|
return $task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function scheduleTask(array $data = array()) {
|
private function scheduleTask(array $data = array(), $priority = null) {
|
||||||
return PhabricatorWorker::scheduleTask('PhabricatorTestWorker', $data);
|
return PhabricatorWorker::scheduleTask(
|
||||||
|
'PhabricatorTestWorker',
|
||||||
|
$data,
|
||||||
|
$priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
|
||||||
|
|
||||||
$leased = 0;
|
$leased = 0;
|
||||||
foreach ($phases as $phase) {
|
foreach ($phases as $phase) {
|
||||||
|
|
||||||
// NOTE: If we issue `UPDATE ... WHERE ... ORDER BY id ASC`, the query
|
// NOTE: If we issue `UPDATE ... WHERE ... ORDER BY id ASC`, the query
|
||||||
// goes very, very slowly. The `ORDER BY` triggers this, although we get
|
// goes very, very slowly. The `ORDER BY` triggers this, although we get
|
||||||
// the same apparent results without it. Without the ORDER BY, binary
|
// the same apparent results without it. Without the ORDER BY, binary
|
||||||
|
@ -126,7 +125,6 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildWhereClause(AphrontDatabaseConnection $conn_w, $phase) {
|
private function buildWhereClause(AphrontDatabaseConnection $conn_w, $phase) {
|
||||||
|
|
||||||
$where = array();
|
$where = array();
|
||||||
|
|
||||||
switch ($phase) {
|
switch ($phase) {
|
||||||
|
@ -141,10 +139,7 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->ids) {
|
if ($this->ids) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf($conn_w, 'id IN (%Ld)', $this->ids);
|
||||||
$conn_w,
|
|
||||||
'id IN (%Ld)',
|
|
||||||
$this->ids);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
@ -162,13 +157,8 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
|
||||||
|
|
||||||
switch ($phase) {
|
switch ($phase) {
|
||||||
case self::PHASE_UNLEASED:
|
case self::PHASE_UNLEASED:
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf($conn_w, 'leaseOwner IS NULL');
|
||||||
$conn_w,
|
$where[] = qsprintf($conn_w, 'id IN (%Ld)', ipull($rows, 'id'));
|
||||||
'leaseOwner IS NULL');
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_w,
|
|
||||||
'id IN (%Ld)',
|
|
||||||
ipull($rows, 'id'));
|
|
||||||
break;
|
break;
|
||||||
case self::PHASE_EXPIRED:
|
case self::PHASE_EXPIRED:
|
||||||
$in = array();
|
$in = array();
|
||||||
|
@ -179,24 +169,20 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
|
||||||
$row['id'],
|
$row['id'],
|
||||||
$row['leaseOwner']);
|
$row['leaseOwner']);
|
||||||
}
|
}
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf($conn_w, '(%Q)', implode(' OR ', $in));
|
||||||
$conn_w,
|
|
||||||
'(%Q)',
|
|
||||||
implode(' OR ', $in));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unknown phase '{$phase}'!");
|
throw new Exception("Unknown phase '{$phase}'!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildOrderClause(AphrontDatabaseConnection $conn_w, $phase) {
|
private function buildOrderClause(AphrontDatabaseConnection $conn_w, $phase) {
|
||||||
switch ($phase) {
|
switch ($phase) {
|
||||||
case self::PHASE_UNLEASED:
|
case self::PHASE_UNLEASED:
|
||||||
// When selecting new tasks, we want to consume them in roughly
|
// When selecting new tasks, we want to consume them in order of
|
||||||
// FIFO order, so we order by the task ID.
|
// decreasing priority (and then FIFO).
|
||||||
return qsprintf($conn_w, 'ORDER BY id ASC');
|
return qsprintf($conn_w, 'ORDER BY id ASC');
|
||||||
case self::PHASE_EXPIRED:
|
case self::PHASE_EXPIRED:
|
||||||
// When selecting failed tasks, we want to consume them in roughly
|
// When selecting failed tasks, we want to consume them in roughly
|
||||||
|
|
|
@ -86,6 +86,7 @@ final class PhabricatorWorkerActiveTask extends PhabricatorWorkerTask {
|
||||||
->setLeaseExpires($this->getLeaseExpires())
|
->setLeaseExpires($this->getLeaseExpires())
|
||||||
->setFailureCount($this->getFailureCount())
|
->setFailureCount($this->getFailureCount())
|
||||||
->setDataID($this->getDataID())
|
->setDataID($this->getDataID())
|
||||||
|
->setPriority($this->getPriority())
|
||||||
->setResult($result)
|
->setResult($result)
|
||||||
->setDuration($duration);
|
->setDuration($duration);
|
||||||
|
|
||||||
|
@ -164,12 +165,11 @@ final class PhabricatorWorkerActiveTask extends PhabricatorWorkerTask {
|
||||||
if ($did_succeed) {
|
if ($did_succeed) {
|
||||||
foreach ($worker->getQueuedTasks() as $task) {
|
foreach ($worker->getQueuedTasks() as $task) {
|
||||||
list($class, $data) = $task;
|
list($class, $data) = $task;
|
||||||
PhabricatorWorker::scheduleTask($class, $data);
|
PhabricatorWorker::scheduleTask($class, $data, $this->getPriority());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,7 @@ final class PhabricatorWorkerArchiveTask extends PhabricatorWorkerTask {
|
||||||
|
|
||||||
public function save() {
|
public function save() {
|
||||||
if ($this->getID() === null) {
|
if ($this->getID() === null) {
|
||||||
throw new Exception(
|
throw new Exception('Trying to archive a task with no ID.');
|
||||||
'Trying to archive a task with no ID.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$other = new PhabricatorWorkerActiveTask();
|
$other = new PhabricatorWorkerActiveTask();
|
||||||
|
@ -57,6 +56,7 @@ final class PhabricatorWorkerArchiveTask extends PhabricatorWorkerTask {
|
||||||
->setLeaseExpires(0)
|
->setLeaseExpires(0)
|
||||||
->setFailureCount(0)
|
->setFailureCount(0)
|
||||||
->setDataID($this->getDataID())
|
->setDataID($this->getDataID())
|
||||||
|
->setPriority($this->getPriority())
|
||||||
->insert();
|
->insert();
|
||||||
|
|
||||||
$this->setDataID(null);
|
$this->setDataID(null);
|
||||||
|
|
|
@ -9,33 +9,34 @@ abstract class PhabricatorWorkerTask extends PhabricatorWorkerDAO {
|
||||||
protected $leaseExpires;
|
protected $leaseExpires;
|
||||||
protected $failureCount;
|
protected $failureCount;
|
||||||
protected $dataID;
|
protected $dataID;
|
||||||
|
protected $priority;
|
||||||
|
|
||||||
private $data;
|
private $data;
|
||||||
private $executionException;
|
private $executionException;
|
||||||
|
|
||||||
public function setExecutionException(Exception $execution_exception) {
|
final public function setExecutionException(Exception $execution_exception) {
|
||||||
$this->executionException = $execution_exception;
|
$this->executionException = $execution_exception;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExecutionException() {
|
final public function getExecutionException() {
|
||||||
return $this->executionException;
|
return $this->executionException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setData($data) {
|
final public function setData($data) {
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData() {
|
final public function getData() {
|
||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isArchived() {
|
final public function isArchived() {
|
||||||
return ($this instanceof PhabricatorWorkerArchiveTask);
|
return ($this instanceof PhabricatorWorkerArchiveTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWorkerInstance() {
|
final public function getWorkerInstance() {
|
||||||
$id = $this->getID();
|
$id = $this->getID();
|
||||||
$class = $this->getTaskClass();
|
$class = $this->getTaskClass();
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ abstract class PhabricatorSMSImplementationAdapter {
|
||||||
'PhabricatorSMSDemultiplexWorker',
|
'PhabricatorSMSDemultiplexWorker',
|
||||||
array(
|
array(
|
||||||
'toNumbers' => $to_numbers,
|
'toNumbers' => $to_numbers,
|
||||||
'body' => $body));
|
'body' => $body,
|
||||||
|
),
|
||||||
|
PhabricatorWorker::PRIORITY_ALERTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue