Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14355757
D10766.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D10766.diff
View Options
diff --git a/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php b/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php
--- a/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php
+++ b/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php
@@ -126,58 +126,21 @@
$daemon_table->setUser($user);
$daemon_table->setDaemonLogs($logs);
- $tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
- 'leaseOwner IS NOT NULL');
-
- $rows = array();
- foreach ($tasks as $task) {
- $rows[] = array(
- $task->getID(),
- $task->getTaskClass(),
- $task->getLeaseOwner(),
- $task->getLeaseExpires() - time(),
- $task->getPriority(),
- $task->getFailureCount(),
- phutil_tag(
- 'a',
- array(
- 'href' => '/daemon/task/'.$task->getID().'/',
- 'class' => 'button small grey',
- ),
- pht('View Task')),
- );
- }
-
$daemon_panel = new PHUIObjectBoxView();
$daemon_panel->setHeaderText(pht('Active Daemons'));
$daemon_panel->appendChild($daemon_table);
- $leased_table = new AphrontTableView($rows);
- $leased_table->setHeaders(
- array(
- pht('ID'),
- pht('Class'),
- pht('Owner'),
- pht('Expires'),
- pht('Priority'),
- pht('Failures'),
- '',
- ));
- $leased_table->setColumnClasses(
- array(
- 'n',
- 'wide',
- '',
- '',
- 'n',
- 'n',
- 'action',
- ));
- $leased_table->setNoDataString(pht('No tasks are leased by workers.'));
- $leased_panel = new PHUIObjectBoxView();
- $leased_panel->setHeaderText(pht('Leased Tasks'));
- $leased_panel->appendChild($leased_table);
+ $tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
+ 'leaseOwner IS NOT NULL');
+
+ $tasks_table = $this->renderTasksTable(
+ $tasks,
+ pht('No tasks are leased by workers.'));
+
+ $leased_panel = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Leased Tasks'))
+ ->appendChild($tasks_table);
$task_table = new PhabricatorWorkerActiveTask();
$queued = queryfx_all(
@@ -211,6 +174,16 @@
$queued_panel->setHeaderText(pht('Queued Tasks'));
$queued_panel->appendChild($queued_table);
+ $upcoming = id(new PhabricatorWorkerLeaseQuery())
+ ->setLimit(10)
+ ->setSkipLease(true)
+ ->execute();
+
+ $upcoming_panel = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Next In Queue'))
+ ->appendChild(
+ $this->renderTasksTable($upcoming, pht('Task queue is empty.')));
+
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Console'));
@@ -223,6 +196,7 @@
$daemon_panel,
$queued_panel,
$leased_panel,
+ $upcoming_panel,
));
return $this->buildApplicationPage(
@@ -233,4 +207,52 @@
));
}
+ private function renderTasksTable(array $tasks, $nodata) {
+ $rows = array();
+ foreach ($tasks as $task) {
+ $rows[] = array(
+ $task->getID(),
+ $task->getTaskClass(),
+ $task->getLeaseOwner(),
+ $task->getLeaseExpires()
+ ? phutil_format_relative_time($task->getLeaseExpires() - time())
+ : '-',
+ $task->getPriority(),
+ $task->getFailureCount(),
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => '/daemon/task/'.$task->getID().'/',
+ 'class' => 'button small grey',
+ ),
+ pht('View Task')),
+ );
+ }
+
+ $table = new AphrontTableView($rows);
+ $table->setHeaders(
+ array(
+ pht('ID'),
+ pht('Class'),
+ pht('Owner'),
+ pht('Expires'),
+ pht('Priority'),
+ pht('Failures'),
+ '',
+ ));
+ $table->setColumnClasses(
+ array(
+ 'n',
+ 'wide',
+ '',
+ '',
+ 'n',
+ 'n',
+ 'action',
+ ));
+ $table->setNoDataString($nodata);
+
+ return $table;
+ }
+
}
diff --git a/src/infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php b/src/infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php
--- a/src/infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php
+++ b/src/infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php
@@ -161,17 +161,17 @@
}
public function testLeasedIsHighestPriority() {
- $task1 = $this->scheduleTask(array(), 2);
+ $task1 = $this->scheduleTask(array(), 1);
$task2 = $this->scheduleTask(array(), 1);
- $task3 = $this->scheduleTask(array(), 1);
+ $task3 = $this->scheduleTask(array(), 2);
$this->expectNextLease(
- $task1,
+ $task3,
'Tasks with a higher priority should be scheduled first.');
$this->expectNextLease(
- $task2,
+ $task1,
'Tasks with the same priority should be FIFO.');
- $this->expectNextLease($task3);
+ $this->expectNextLease($task2);
}
private function expectNextLease($task, $message = null) {
diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php
--- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php
+++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php
@@ -10,6 +10,7 @@
private $ids;
private $limit;
+ private $skipLease;
public static function getDefaultWaitBeforeRetry() {
return phutil_units('5 minutes in seconds');
@@ -19,6 +20,20 @@
return phutil_units('2 hours in seconds');
}
+ /**
+ * Set this flag to select tasks from the top of the queue without leasing
+ * them.
+ *
+ * This can be used to show which tasks are coming up next without altering
+ * the queue's behavior.
+ *
+ * @param bool True to skip the lease acquisition step.
+ */
+ public function setSkipLease($skip) {
+ $this->skipLease = $skip;
+ return $this;
+ }
+
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
@@ -51,6 +66,7 @@
$limit = $this->limit;
$leased = 0;
+ $task_ids = array();
foreach ($phases as $phase) {
// NOTE: If we issue `UPDATE ... WHERE ... ORDER BY id ASC`, the query
// goes very, very slowly. The `ORDER BY` triggers this, although we get
@@ -74,17 +90,23 @@
// total runtime, so keep it simple for the moment.
if ($rows) {
- queryfx(
- $conn_w,
- 'UPDATE %T task
- SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + %d
- %Q',
- $task_table->getTableName(),
- $lease_ownership_name,
- self::getDefaultLeaseDuration(),
- $this->buildUpdateWhereClause($conn_w, $phase, $rows));
-
- $leased += $conn_w->getAffectedRows();
+ if ($this->skipLease) {
+ $leased += count($rows);
+ $task_ids += array_fuse(ipull($rows, 'id'));
+ } else {
+ queryfx(
+ $conn_w,
+ 'UPDATE %T task
+ SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + %d
+ %Q',
+ $task_table->getTableName(),
+ $lease_ownership_name,
+ self::getDefaultLeaseDuration(),
+ $this->buildUpdateWhereClause($conn_w, $phase, $rows));
+
+ $leased += $conn_w->getAffectedRows();
+ }
+
if ($leased == $limit) {
break;
}
@@ -95,16 +117,27 @@
return array();
}
+ if ($this->skipLease) {
+ $selection_condition = qsprintf(
+ $conn_w,
+ 'task.id IN (%Ld)',
+ $task_ids);
+ } else {
+ $selection_condition = qsprintf(
+ $conn_w,
+ 'task.leaseOwner = %s AND leaseExpires > UNIX_TIMESTAMP()',
+ $lease_ownership_name);
+ }
+
$data = queryfx_all(
$conn_w,
'SELECT task.*, taskdata.data _taskData, UNIX_TIMESTAMP() _serverTime
FROM %T task LEFT JOIN %T taskdata
ON taskdata.id = task.dataID
- WHERE leaseOwner = %s AND leaseExpires > UNIX_TIMESTAMP()
- %Q %Q',
+ WHERE %Q %Q %Q',
$task_table->getTableName(),
$taskdata_table->getTableName(),
- $lease_ownership_name,
+ $selection_condition,
$this->buildOrderClause($conn_w, $phase),
$this->buildLimitClause($conn_w, $limit));
@@ -183,7 +216,7 @@
case self::PHASE_UNLEASED:
// When selecting new tasks, we want to consume them in order of
// decreasing priority (and then FIFO).
- return qsprintf($conn_w, 'ORDER BY id ASC');
+ return qsprintf($conn_w, 'ORDER BY priority DESC, id ASC');
case self::PHASE_EXPIRED:
// When selecting failed tasks, we want to consume them in roughly
// FIFO order of their failures, which is not necessarily their original
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 6:18 PM (14 h, 31 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6911530
Default Alt Text
D10766.diff (8 KB)
Attached To
Mode
D10766: Fix daemon task queue to respect task priority
Attached
Detach File
Event Timeline
Log In to Comment