Differential D16906 Diff 40708 src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php
Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php
Show All 10 Lines | return array( | ||||
'repeat' => true, | 'repeat' => true, | ||||
'help' => pht('Select one or more tasks by ID.'), | 'help' => pht('Select one or more tasks by ID.'), | ||||
), | ), | ||||
array( | array( | ||||
'name' => 'class', | 'name' => 'class', | ||||
'param' => 'name', | 'param' => 'name', | ||||
'help' => pht('Select all tasks of a given class.'), | '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) { | protected function loadTasks(PhutilArgumentParser $args) { | ||||
$ids = $args->getArg('id'); | $ids = $args->getArg('id'); | ||||
$class = $args->getArg('class'); | $class = $args->getArg('class'); | ||||
$min_failures = $args->getArg('min-failure-count'); | |||||
if (!$ids && !$class) { | if (!$ids && !$class && !$min_failures) { | ||||
throw new PhutilArgumentUsageException( | throw new PhutilArgumentUsageException( | ||||
pht('Use --id or --class to select tasks.')); | pht('Use --id, --class, or --min-failure-count to select tasks.')); | ||||
} if ($ids && $class) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht('Use one of --id or --class to select tasks, but not both.')); | |||||
} | } | ||||
epriestley: We should probably just accept all selectors and apply them with AND, like UI queries do… | |||||
$active_query = new PhabricatorWorkerActiveTaskQuery(); | |||||
$archive_query = new PhabricatorWorkerArchiveTaskQuery(); | |||||
if ($ids) { | if ($ids) { | ||||
$active_tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( | $active_query = $active_query->withIDs($ids); | ||||
'id IN (%Ls)', | $archive_query = $archive_query->withIDs($ids); | ||||
$ids); | } | ||||
$archive_tasks = id(new PhabricatorWorkerArchiveTaskQuery()) | |||||
->withIDs($ids) | if ($class) { | ||||
->execute(); | $class_array = array($class); | ||||
} else { | $active_query = $active_query->withClassNames($class_array); | ||||
$active_tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( | $archive_query = $archive_query->withClassNames($class_array); | ||||
'taskClass IN (%Ls)', | } | ||||
array($class)); | |||||
$archive_tasks = id(new PhabricatorWorkerArchiveTaskQuery()) | if ($min_failures) { | ||||
->withClassNames(array($class)) | $active_query = $active_query->withFailureCountBetween( | ||||
->execute(); | $min_failures, null); | ||||
$archive_query = $archive_query->withFailureCountBetween( | |||||
$min_failures, null); | |||||
} | } | ||||
$active_tasks = $active_query->execute(); | |||||
$archive_tasks = $archive_query->execute(); | |||||
$tasks = | $tasks = | ||||
mpull($active_tasks, null, 'getID') + | mpull($active_tasks, null, 'getID') + | ||||
mpull($archive_tasks, null, 'getID'); | mpull($archive_tasks, null, 'getID'); | ||||
if ($ids) { | if ($ids) { | ||||
foreach ($ids as $id) { | foreach ($ids as $id) { | ||||
if (empty($tasks[$id])) { | if (empty($tasks[$id])) { | ||||
throw new PhutilArgumentUsageException( | throw new PhutilArgumentUsageException( | ||||
pht('No task exists with id "%s"!', $id)); | pht('No task exists with id "%s"!', $id)); | ||||
} | } | ||||
} | } | ||||
} else { | } | ||||
if ($class && $min_failures) { | |||||
if (!$tasks) { | |||||
throw new PhutilArgumentUsageException( | |||||
pht('No task exists with class "%s" and at least %d failures!', | |||||
$class, | |||||
$min_failures)); | |||||
} | |||||
} else if ($class) { | |||||
if (!$tasks) { | if (!$tasks) { | ||||
throw new PhutilArgumentUsageException( | throw new PhutilArgumentUsageException( | ||||
pht('No task exists with class "%s"!', $class)); | pht('No task exists with class "%s"!', $class)); | ||||
} | } | ||||
} else if ($min_failures) { | |||||
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 | // When we lock tasks properly, this gets populated as a side effect. Just | ||||
// fake it when doing manual CLI stuff. This makes sure CLI yields have | // fake it when doing manual CLI stuff. This makes sure CLI yields have | ||||
// their expires times set properly. | // their expires times set properly. | ||||
foreach ($tasks as $task) { | foreach ($tasks as $task) { | ||||
if ($task instanceof PhabricatorWorkerActiveTask) { | if ($task instanceof PhabricatorWorkerActiveTask) { | ||||
$task->setServerTime(PhabricatorTime::getNow()); | $task->setServerTime(PhabricatorTime::getNow()); | ||||
Show All 11 Lines |
We should probably just accept all selectors and apply them with AND, like UI queries do, although I guess the fact that we aren't using a real Query object further down makes this harder.
That is, doesn't seem inherently wrong to accept --id 1 --id 2 --id 3 --class X as "all tasks with class X and IDs 1, 2 or 3".
Not a big deal either way.