1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 03:50:54 +01:00

Allow archived tasks to be queried by object PHID and order by id

Summary: Ref T5402.

Test Plan:
  - Queried archived tasks.
  - Grepped for use sites and verified no other callsites are order-sensitive.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T5402

Differential Revision: https://secure.phabricator.com/D11089
This commit is contained in:
epriestley 2014-12-30 15:54:56 -08:00
parent 12c7c399ce
commit ba4ebf28ad
5 changed files with 83 additions and 10 deletions

View file

@ -131,8 +131,11 @@ final class PhabricatorDaemonConsoleController
$daemon_panel->appendChild($daemon_table); $daemon_panel->appendChild($daemon_table);
$tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( $tasks = id(new PhabricatorWorkerLeaseQuery())
'leaseOwner IS NOT NULL'); ->setSkipLease(true)
->withLeasedTasks(true)
->setLimit(100)
->execute();
$tasks_table = id(new PhabricatorDaemonTasksTableView()) $tasks_table = id(new PhabricatorDaemonTasksTableView())
->setTasks($tasks) ->setTasks($tasks)

View file

@ -6,6 +6,7 @@ final class PhabricatorWorkerArchiveTaskQuery
private $ids; private $ids;
private $dateModifiedSince; private $dateModifiedSince;
private $dateCreatedBefore; private $dateCreatedBefore;
private $objectPHIDs;
private $limit; private $limit;
public function withIDs(array $ids) { public function withIDs(array $ids) {
@ -23,20 +24,24 @@ final class PhabricatorWorkerArchiveTaskQuery
return $this; return $this;
} }
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
public function setLimit($limit) { public function setLimit($limit) {
$this->limit = $limit; $this->limit = $limit;
return $this; return $this;
} }
public function execute() { public function execute() {
$task_table = new PhabricatorWorkerArchiveTask(); $task_table = new PhabricatorWorkerArchiveTask();
$conn_r = $task_table->establishConnection('r'); $conn_r = $task_table->establishConnection('r');
$rows = queryfx_all( $rows = queryfx_all(
$conn_r, $conn_r,
'SELECT * FROM %T %Q %Q', 'SELECT * FROM %T %Q ORDER BY id DESC %Q',
$task_table->getTableName(), $task_table->getTableName(),
$this->buildWhereClause($conn_r), $this->buildWhereClause($conn_r),
$this->buildLimitClause($conn_r)); $this->buildLimitClause($conn_r));
@ -54,6 +59,13 @@ final class PhabricatorWorkerArchiveTaskQuery
$this->ids); $this->ids);
} }
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
if ($this->dateModifiedSince) { if ($this->dateModifiedSince) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,

View file

@ -5,6 +5,7 @@
*/ */
final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery { final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
const PHASE_LEASED = 'leased';
const PHASE_UNLEASED = 'unleased'; const PHASE_UNLEASED = 'unleased';
const PHASE_EXPIRED = 'expired'; const PHASE_EXPIRED = 'expired';
@ -12,6 +13,7 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
private $objectPHIDs; private $objectPHIDs;
private $limit; private $limit;
private $skipLease; private $skipLease;
private $leased = false;
public static function getDefaultWaitBeforeRetry() { public static function getDefaultWaitBeforeRetry() {
return phutil_units('5 minutes in seconds'); return phutil_units('5 minutes in seconds');
@ -45,6 +47,26 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
return $this; return $this;
} }
/**
* Select only leased tasks, only unleased tasks, or both types of task.
*
* By default, queries select only unleased tasks (equivalent to passing
* `false` to this method). You can pass `true` to select only leased tasks,
* or `null` to ignore the lease status of tasks.
*
* If your result set potentially includes leased tasks, you must disable
* leasing using @{method:setSkipLease}. These options are intended for use
* when displaying task status information.
*
* @param mixed `true` to select only leased tasks, `false` to select only
* unleased tasks (default), or `null` to select both.
* @return this
*/
public function withLeasedTasks($leased) {
$this->leased = $leased;
return $this;
}
public function setLimit($limit) { public function setLimit($limit) {
$this->limit = $limit; $this->limit = $limit;
return $this; return $this;
@ -52,7 +74,17 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
public function execute() { public function execute() {
if (!$this->limit) { if (!$this->limit) {
throw new Exception('You must setLimit() when leasing tasks.'); throw new Exception(
pht('You must setLimit() when leasing tasks.'));
}
if ($this->leased !== false) {
if (!$this->skipLease) {
throw new Exception(
pht(
'If you potentially select leased tasks using withLeasedTasks(), '.
'you MUST disable lease acquisition by calling setSkipLease().'));
}
} }
$task_table = new PhabricatorWorkerActiveTask(); $task_table = new PhabricatorWorkerActiveTask();
@ -65,10 +97,16 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
// find enough tasks, try tasks with expired leases (i.e., tasks which have // find enough tasks, try tasks with expired leases (i.e., tasks which have
// previously failed). // previously failed).
$phases = array( // If we're selecting leased tasks, look for them first.
self::PHASE_UNLEASED,
self::PHASE_EXPIRED, $phases = array();
); if ($this->leased !== false) {
$phases[] = self::PHASE_LEASED;
}
if ($this->leased !== true) {
$phases[] = self::PHASE_UNLEASED;
$phases[] = self::PHASE_EXPIRED;
}
$limit = $this->limit; $limit = $this->limit;
$leased = 0; $leased = 0;
@ -160,6 +198,11 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
$tasks[$row['id']]->setData($task_data); $tasks[$row['id']]->setData($task_data);
} }
if ($this->skipLease) {
// Reorder rows into the original phase order if this is a status query.
$tasks = array_select_keys($tasks, $task_ids);
}
return $tasks; return $tasks;
} }
@ -167,6 +210,10 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
$where = array(); $where = array();
switch ($phase) { switch ($phase) {
case self::PHASE_LEASED:
$where[] = 'leaseOwner IS NOT NULL';
$where[] = 'leaseExpires >= UNIX_TIMESTAMP()';
break;
case self::PHASE_UNLEASED: case self::PHASE_UNLEASED:
$where[] = 'leaseOwner IS NULL'; $where[] = 'leaseOwner IS NULL';
break; break;
@ -177,7 +224,7 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
throw new Exception("Unknown phase '{$phase}'!"); throw new Exception("Unknown phase '{$phase}'!");
} }
if ($this->ids) { if ($this->ids !== null) {
$where[] = qsprintf($conn_w, 'id IN (%Ld)', $this->ids); $where[] = qsprintf($conn_w, 'id IN (%Ld)', $this->ids);
} }
@ -199,6 +246,11 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
// `IN (NULL)` doesn't match NULL. // `IN (NULL)` doesn't match NULL.
switch ($phase) { switch ($phase) {
case self::PHASE_LEASED:
throw new Exception(
pht(
'Trying to lease tasks selected in the leased phase! This is '.
'intended to be imposssible.'));
case self::PHASE_UNLEASED: case self::PHASE_UNLEASED:
$where[] = qsprintf($conn_w, 'leaseOwner IS NULL'); $where[] = qsprintf($conn_w, 'leaseOwner IS NULL');
$where[] = qsprintf($conn_w, 'id IN (%Ld)', ipull($rows, 'id')); $where[] = qsprintf($conn_w, 'id IN (%Ld)', ipull($rows, 'id'));
@ -223,6 +275,10 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
private function buildOrderClause(AphrontDatabaseConnection $conn_w, $phase) { private function buildOrderClause(AphrontDatabaseConnection $conn_w, $phase) {
switch ($phase) { switch ($phase) {
case self::PHASE_LEASED:
// Ideally we'd probably order these by lease acquisition time, but
// we don't have that handy and this is a good approximation.
return qsprintf($conn_w, 'ORDER BY priority ASC, id ASC');
case self::PHASE_UNLEASED: case self::PHASE_UNLEASED:
// When selecting new tasks, we want to consume them in order of // When selecting new tasks, we want to consume them in order of
// increasing priority (and then FIFO). // increasing priority (and then FIFO).

View file

@ -119,6 +119,7 @@ final class PhabricatorWorkerActiveTask extends PhabricatorWorkerTask {
->setFailureCount($this->getFailureCount()) ->setFailureCount($this->getFailureCount())
->setDataID($this->getDataID()) ->setDataID($this->getDataID())
->setPriority($this->getPriority()) ->setPriority($this->getPriority())
->setObjectPHID($this->getObjectPHID())
->setResult($result) ->setResult($result)
->setDuration($duration); ->setDuration($duration);

View file

@ -84,6 +84,7 @@ final class PhabricatorWorkerArchiveTask extends PhabricatorWorkerTask {
->setFailureCount(0) ->setFailureCount(0)
->setDataID($this->getDataID()) ->setDataID($this->getDataID())
->setPriority($this->getPriority()) ->setPriority($this->getPriority())
->setObjectPHID($this->getObjectPHID())
->insert(); ->insert();
$this->setDataID(null); $this->setDataID(null);