From e4eba1eef182995df100329e240ee7f3c0f70cf4 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Tue, 12 May 2026 13:10:19 +0200 Subject: [PATCH] feat(task-streaming): add an endpoint to set a task intermediate output Signed-off-by: Julien Veyssier --- .../TaskProcessingApiController.php | 31 +++++++++++++++++++ lib/private/TaskProcessing/Manager.php | 2 +- lib/public/TaskProcessing/IManager.php | 10 ++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/core/Controller/TaskProcessingApiController.php b/core/Controller/TaskProcessingApiController.php index ac81af45f0b..dc335e89efe 100644 --- a/core/Controller/TaskProcessingApiController.php +++ b/core/Controller/TaskProcessingApiController.php @@ -643,6 +643,37 @@ class TaskProcessingApiController extends OCSController { } } + /** + * Sets the task intermediate result while it is running + * + * @param int $taskId The id of the task + * @param array|null $output The intermediate task output, files are represented by their IDs + * @return DataResponse|DataResponse + * + * 200: Result updated successfully + * 404: Task not found + */ + #[ExAppRequired] + #[ApiRoute(verb: 'POST', url: '/tasks_provider/{taskId}/stream-result', root: '/taskprocessing')] + public function setIntermediateResult(int $taskId, array $output): DataResponse { + try { + // set result + $this->taskProcessingManager->setTaskIntermediateOutput($taskId, $output); + $task = $this->taskProcessingManager->getTask($taskId); + + /** @var CoreTaskProcessingTask $json */ + $json = $task->jsonSerialize(); + + return new DataResponse([ + 'task' => $json, + ]); + } catch (NotFoundException) { + return new DataResponse(['message' => $this->l->t('Not found')], Http::STATUS_NOT_FOUND); + } catch (Exception) { + return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR); + } + } + /** * @return DataResponse|DataResponse */ diff --git a/lib/private/TaskProcessing/Manager.php b/lib/private/TaskProcessing/Manager.php index b11c022944d..c3595c77cc3 100644 --- a/lib/private/TaskProcessing/Manager.php +++ b/lib/private/TaskProcessing/Manager.php @@ -1230,7 +1230,7 @@ class Manager implements IManager { public function setTaskIntermediateOutput(int $id, array $output): bool { // TODO: Not sure if we should rather catch the exceptions of getTask here and fail silently $task = $this->getTask($id); - if ($task->getStatus() === Task::STATUS_CANCELLED) { + if ($task->getStatus() !== Task::STATUS_RUNNING) { return false; } $userId = $task->getUserId(); diff --git a/lib/public/TaskProcessing/IManager.php b/lib/public/TaskProcessing/IManager.php index f15cecddc7b..2d102cc0937 100644 --- a/lib/public/TaskProcessing/IManager.php +++ b/lib/public/TaskProcessing/IManager.php @@ -142,6 +142,16 @@ interface IManager { */ public function setTaskResult(int $id, ?string $error, ?array $result, bool $isUsingFileIds = false, ?string $userFacingError = null): void; + /** + * @param int $id The id of the task + * @param array $output + * @return bool `true` if the task should still be running; `false` if the task has been cancelled in the meantime + * @throws Exception If the query failed + * @throws NotFoundException If the task could not be found + * @since 34.0.0 + */ + public function setTaskIntermediateOutput(int $id, array $output): bool; + /** * @param int $id * @param float $progress