Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions core/Controller/TaskProcessingApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,42 @@ public function listTasks(?string $taskType, ?string $customId = null): DataResp
}
}

/**
* Returns queue statistics for task processing
*
* Returns the count of scheduled and running tasks, optionally filtered
* by task type(s). Designed for external scalers (e.g. KEDA) to poll
* for task queue depth. Admin-only endpoint authenticated via app_password.
*
* @param string|null $taskTypeId Comma-separated list of task type IDs to filter by
* @return DataResponse<Http::STATUS_OK, array{scheduled: int, running: int}, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
*
* 200: Queue stats returned
*/
#[NoCSRFRequired]
#[ApiRoute(verb: 'GET', url: '/queue_stats', root: '/taskprocessing')]
public function queueStats(?string $taskTypeId = null): DataResponse {
# TODO: bruteforce protection?
try {
$taskTypeIds = [];
if ($taskTypeId !== null) {
$taskTypeIds = array_map('trim', explode(',', $taskTypeId));
$taskTypeIds = array_filter($taskTypeIds, fn (string $id) => $id !== '');
$taskTypeIds = array_values($taskTypeIds);
}

$scheduled = $this->taskProcessingManager->countTasks(Task::STATUS_SCHEDULED, $taskTypeIds);
$running = $this->taskProcessingManager->countTasks(Task::STATUS_RUNNING, $taskTypeIds);

return new DataResponse([
'scheduled' => $scheduled,
'running' => $running,
]);
} catch (Exception) {
return new DataResponse(['message' => $this->l->t('Internal error')], Http::STATUS_INTERNAL_SERVER_ERROR);
}
}

/**
* Returns the contents of a file referenced in a task
*
Expand Down
20 changes: 20 additions & 0 deletions lib/private/TaskProcessing/Db/TaskMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,26 @@ public function findNOldestScheduledByType(array $taskTypes, array $taskIdsToIgn
return $this->findEntities($qb);
}

/**
* @param list<string> $taskTypeIds
* @param int $status
* @return int
* @throws Exception
*/
public function countByStatus(array $taskTypeIds, int $status): int {
$qb = $this->db->getQueryBuilder();
$qb->select($qb->func()->count('id'))
->from($this->tableName)
->where($qb->expr()->eq('status', $qb->createNamedParameter($status, IQueryBuilder::PARAM_INT)));
if (!empty($taskTypeIds)) {
$qb->andWhere($qb->expr()->in('type', $qb->createNamedParameter($taskTypeIds, IQueryBuilder::PARAM_STR_ARRAY)));
}
$result = $qb->executeQuery();
$count = (int)$result->fetchOne();
$result->closeCursor();
return $count;
}

/**
* @throws Exception
*/
Expand Down
8 changes: 8 additions & 0 deletions lib/private/TaskProcessing/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,14 @@ public function getTasks(
}
}

public function countTasks(int $status, array $taskTypeIds = []): int {
try {
return $this->taskMapper->countByStatus($taskTypeIds, $status);
} catch (\OCP\DB\Exception $e) {
throw new \OCP\TaskProcessing\Exception\Exception('There was a problem counting the tasks', 0, $e);
}
}

public function getUserTasksByApp(?string $userId, string $appId, ?string $customId = null): array {
try {
$taskEntities = $this->taskMapper->findUserTasksByApp($userId, $appId, $customId);
Expand Down
11 changes: 11 additions & 0 deletions lib/public/TaskProcessing/IManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,17 @@ public function lockTask(Task $task): bool;
*/
public function setTaskStatus(Task $task, int $status): void;

/**
* Get the count of tasks filtered by status and optionally by task type(s)
*
* @param int $status The task status to filter by
* @param list<string> $taskTypeIds Optional list of task type IDs to filter by
* @return int The count of matching tasks
* @throws Exception If the query failed
* @since 34.0.0
*/
public function countTasks(int $status, array $taskTypeIds = []): int;

/**
* Extract all input and output file IDs from a task
*
Expand Down
Loading