diff --git a/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php --- a/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php +++ b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php @@ -16,14 +16,20 @@ 'param' => 'name', 'help' => pht('Select all tasks of a given class.'), ), + array( + 'name' => 'min-failure-count', + 'param' => 'int', + 'help' => pht('Limit to tasks with at least this many failures.'), + ), ); } protected function loadTasks(PhutilArgumentParser $args) { $ids = $args->getArg('id'); $class = $args->getArg('class'); + $min_failures = $args->getArg('min-failure-count'); - if (!$ids && !$class) { + if (!$ids && !$class && !$min_failures) { throw new PhutilArgumentUsageException( pht('Use --id or --class to select tasks.')); } if ($ids && $class) { @@ -31,6 +37,10 @@ pht('Use one of --id or --class to select tasks, but not both.')); } + if (!$min_failures) { + $min_failures = 0; + } + if ($ids) { $active_tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( 'id IN (%Ls)', @@ -38,12 +48,21 @@ $archive_tasks = id(new PhabricatorWorkerArchiveTaskQuery()) ->withIDs($ids) ->execute(); - } else { + } else if ($class) { $active_tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( - 'taskClass IN (%Ls)', - array($class)); + 'taskClass IN (%Ls) AND failureCount >= %d', + array($class), + $min_failures); $archive_tasks = id(new PhabricatorWorkerArchiveTaskQuery()) ->withClassNames(array($class)) + ->withMinFailureCount($min_failures) + ->execute(); + } else { + $active_tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( + 'failureCount >= %d', + $min_failures); + $archive_tasks = id(new PhabricatorWorkerArchiveTaskQuery()) + ->withMinFailureCount($min_failures) ->execute(); } @@ -58,11 +77,16 @@ pht('No task exists with id "%s"!', $id)); } } - } else { + } else if ($class) { if (!$tasks) { throw new PhutilArgumentUsageException( pht('No task exists with class "%s"!', $class)); } + } else { + if (!$tasks) { + throw new PhutilArgumentUsageException( + pht('No tasks exist with at least %d failures!', $min_failures)); + } } // When we lock tasks properly, this gets populated as a side effect. Just diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php --- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php +++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerArchiveTaskQuery.php @@ -9,6 +9,7 @@ private $objectPHIDs; private $classNames; private $limit; + private $minFailureCount; public function withIDs(array $ids) { $this->ids = $ids; @@ -35,6 +36,11 @@ return $this; } + public function withMinFailureCount($min) { + $this->minFailureCount = $min; + return $this; + } + public function setLimit($limit) { $this->limit = $limit; return $this; @@ -94,6 +100,13 @@ $this->classNames); } + if ($this->minFailureCount !== null) { + $where[] = qsprintf( + $conn_r, + 'failureCount >= %d', + $this->minFailureCount); + } + return $this->formatWhereClause($where); }