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);
$tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
'leaseOwner IS NOT NULL');
$tasks = id(new PhabricatorWorkerLeaseQuery())
->setSkipLease(true)
->withLeasedTasks(true)
->setLimit(100)
->execute();
$tasks_table = id(new PhabricatorDaemonTasksTableView())
->setTasks($tasks)

View file

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

View file

@ -5,6 +5,7 @@
*/
final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
const PHASE_LEASED = 'leased';
const PHASE_UNLEASED = 'unleased';
const PHASE_EXPIRED = 'expired';
@ -12,6 +13,7 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
private $objectPHIDs;
private $limit;
private $skipLease;
private $leased = false;
public static function getDefaultWaitBeforeRetry() {
return phutil_units('5 minutes in seconds');
@ -45,6 +47,26 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
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) {
$this->limit = $limit;
return $this;
@ -52,7 +74,17 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
public function execute() {
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();
@ -65,10 +97,16 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
// find enough tasks, try tasks with expired leases (i.e., tasks which have
// previously failed).
$phases = array(
self::PHASE_UNLEASED,
self::PHASE_EXPIRED,
);
// If we're selecting leased tasks, look for them first.
$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;
$leased = 0;
@ -160,6 +198,11 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
$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;
}
@ -167,6 +210,10 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
$where = array();
switch ($phase) {
case self::PHASE_LEASED:
$where[] = 'leaseOwner IS NOT NULL';
$where[] = 'leaseExpires >= UNIX_TIMESTAMP()';
break;
case self::PHASE_UNLEASED:
$where[] = 'leaseOwner IS NULL';
break;
@ -177,7 +224,7 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
throw new Exception("Unknown phase '{$phase}'!");
}
if ($this->ids) {
if ($this->ids !== null) {
$where[] = qsprintf($conn_w, 'id IN (%Ld)', $this->ids);
}
@ -199,6 +246,11 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
// `IN (NULL)` doesn't match NULL.
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:
$where[] = qsprintf($conn_w, 'leaseOwner IS NULL');
$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) {
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:
// When selecting new tasks, we want to consume them in order of
// increasing priority (and then FIFO).

View file

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

View file

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