diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5145,9 +5145,11 @@ 'PhabricatorWorkerDestructionEngineExtension' => 'infrastructure/daemon/workers/engineextension/PhabricatorWorkerDestructionEngineExtension.php', 'PhabricatorWorkerLeaseQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php', 'PhabricatorWorkerManagementCancelWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementCancelWorkflow.php', + 'PhabricatorWorkerManagementDelayWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementDelayWorkflow.php', 'PhabricatorWorkerManagementExecuteWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementExecuteWorkflow.php', 'PhabricatorWorkerManagementFloodWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementFloodWorkflow.php', 'PhabricatorWorkerManagementFreeWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementFreeWorkflow.php', + 'PhabricatorWorkerManagementPriorityWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementPriorityWorkflow.php', 'PhabricatorWorkerManagementRetryWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementRetryWorkflow.php', 'PhabricatorWorkerManagementWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php', 'PhabricatorWorkerPermanentFailureException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerPermanentFailureException.php', @@ -11973,9 +11975,11 @@ 'PhabricatorWorkerDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension', 'PhabricatorWorkerLeaseQuery' => 'PhabricatorQuery', 'PhabricatorWorkerManagementCancelWorkflow' => 'PhabricatorWorkerManagementWorkflow', + 'PhabricatorWorkerManagementDelayWorkflow' => 'PhabricatorWorkerManagementWorkflow', 'PhabricatorWorkerManagementExecuteWorkflow' => 'PhabricatorWorkerManagementWorkflow', 'PhabricatorWorkerManagementFloodWorkflow' => 'PhabricatorWorkerManagementWorkflow', 'PhabricatorWorkerManagementFreeWorkflow' => 'PhabricatorWorkerManagementWorkflow', + 'PhabricatorWorkerManagementPriorityWorkflow' => 'PhabricatorWorkerManagementWorkflow', 'PhabricatorWorkerManagementRetryWorkflow' => 'PhabricatorWorkerManagementWorkflow', 'PhabricatorWorkerManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorWorkerPermanentFailureException' => 'Exception', diff --git a/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementDelayWorkflow.php b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementDelayWorkflow.php new file mode 100644 --- /dev/null +++ b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementDelayWorkflow.php @@ -0,0 +1,97 @@ +setName('delay') + ->setExamples( + implode( + "\n", + array( + '**delay** __selectors__ --until __date__', + '**delay** __selectors__ --until __YYYY-MM-DD__', + '**delay** __selectors__ --until "6 hours"', + '**delay** __selectors__ --until now', + ))) + ->setSynopsis( + pht( + 'Delay execution of selected tasks until the specified time.')) + ->setArguments( + array_merge( + array( + array( + 'name' => 'until', + 'param' => 'date', + 'help' => pht( + 'Select the date or time to delay the selected tasks until.'), + ), + ), + $this->getTaskSelectionArguments())); + } + + public function execute(PhutilArgumentParser $args) { + $viewer = $this->getViewer(); + + $until = $args->getArg('until'); + $until = $this->parseTimeArgument($until); + + if ($until === null) { + throw new PhutilArgumentUsageException( + pht( + 'Specify how long to delay tasks for with "--until".')); + } + + $tasks = $this->loadTasks($args); + + if (!$tasks) { + $this->logWarn( + pht('NO TASKS'), + pht('No tasks selected to delay.')); + + return 0; + } + + $delay_count = 0; + foreach ($tasks as $task) { + if ($task->isArchived()) { + $this->logWarn( + pht('ARCHIVED'), + pht( + '%s is already archived, and can not be delayed.', + $this->describeTask($task))); + continue; + } + + if ($task->getLeaseOwner()) { + $this->logWarn( + pht('LEASED'), + pht( + '% is already leased, and can not be delayed.', + $this->describeTask($task))); + continue; + } + + $task + ->setLeaseExpires($until) + ->save(); + + $this->logInfo( + pht('DELAY'), + pht( + '%s was delayed until "%s".', + $this->describeTask($task), + phabricator_datetime($until, $viewer))); + + $delay_count++; + } + + $this->logOkay( + pht('DONE'), + pht('Delayed %s task(s).', new PhutilNumber($delay_count))); + + return 0; + } + +} diff --git a/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementPriorityWorkflow.php b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementPriorityWorkflow.php new file mode 100644 --- /dev/null +++ b/src/infrastructure/daemon/workers/management/PhabricatorWorkerManagementPriorityWorkflow.php @@ -0,0 +1,102 @@ +setName('priority') + ->setExamples('**priority** __selectors__ --priority __value__') + ->setSynopsis( + pht( + 'Change the priority of selected tasks, causing them to execute '. + 'before or after other tasks.')) + ->setArguments( + array_merge( + array( + array( + 'name' => 'priority', + 'param' => 'int', + 'help' => pht( + 'Set tasks to this priority. Tasks with a smaller priority '. + 'value execute before tasks with a larger priority value.'), + ), + ), + $this->getTaskSelectionArguments())); + } + + public function execute(PhutilArgumentParser $args) { + $new_priority = $args->getArg('priority'); + + if ($new_priority === null) { + throw new PhutilArgumentUsageException( + pht( + 'Select a new priority for selected tasks with "--priority".')); + } + + $new_priority = (int)$new_priority; + if ($new_priority <= 0) { + throw new PhutilArgumentUsageException( + pht( + 'Priority must be a positive integer.')); + } + + $tasks = $this->loadTasks($args); + + if (!$tasks) { + $this->logWarn( + pht('NO TASKS'), + pht('No tasks selected to reprioritize.')); + + return 0; + } + + $priority_count = 0; + foreach ($tasks as $task) { + $can_reprioritize = !$task->isArchived(); + if (!$can_reprioritize) { + $this->logWarn( + pht('ARCHIVED'), + pht( + '%s is already archived, and can not be reprioritized.', + $this->describeTask($task))); + continue; + } + + + $old_priority = (int)$task->getPriority(); + + if ($old_priority === $new_priority) { + $this->logWarn( + pht('UNCHANGED'), + pht( + '%s already has priority "%s".', + $this->describeTask($task), + $new_priority)); + continue; + } + + + $task + ->setPriority($new_priority) + ->save(); + + $this->logInfo( + pht('PRIORITY'), + pht( + '%s was reprioritized (from "%d" to "%d").', + $this->describeTask($task), + $old_priority, + $new_priority)); + + $priority_count++; + } + + $this->logOkay( + pht('DONE'), + pht('Reprioritized %s task(s).', new PhutilNumber($priority_count))); + + return 0; + } + +} diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php --- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php +++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php @@ -1759,6 +1759,36 @@ 'These inline comments will be saved and published.', ), + 'Delayed %s task(s).' => array( + 'Delayed 1 task.', + 'Delayed %s tasks.', + ), + + 'Freed %s task lease(s).' => array( + 'Freed 1 task lease.', + 'Freed %s task leases.', + ), + + 'Cancelled %s task(s).' => array( + 'Cancelled 1 task.', + 'Cancelled %s tasks.', + ), + + 'Queued %s task(s) for retry.' => array( + 'Queued 1 task for retry.', + 'Queued %s tasks for retry.', + ), + + 'Reprioritized %s task(s).' => array( + 'Reprioritized one task.', + 'Reprioritized %s tasks.', + ), + + 'Executed %s task(s).' => array( + 'Executed 1 task.', + 'Executed %s tasks.', + ), + ); }