Page MenuHomePhabricator

D10766.diff
No OneTemporary

D10766.diff

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

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)

Event Timeline