From 6becf1f1743753d1343d8ade9e1be5d14f7a1baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 19 Apr 2025 20:34:05 +0200 Subject: [PATCH] add docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/dirty-grapes-vanish.md | 2 +- .../backend-system/core-services/scheduler.md | 91 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/.changeset/dirty-grapes-vanish.md b/.changeset/dirty-grapes-vanish.md index 42f7157b80..128b403bae 100644 --- a/.changeset/dirty-grapes-vanish.md +++ b/.changeset/dirty-grapes-vanish.md @@ -2,4 +2,4 @@ '@backstage/backend-defaults': patch --- -The `DefaultSchedulerService` now accepts `HttpRouterService` and `PluginMetadataService` arguments. If you supply a router, the scheduler will register a REST API for listing and triggering tasks. +The `DefaultSchedulerService` now accepts `HttpRouterService` and `PluginMetadataService` arguments. If you supply a router, the scheduler will register a REST API for listing and triggering tasks. Please see [the scheduler documentation](https://backstage.io/docs/backend-system/core-services/scheduler) for more details about this API. diff --git a/docs/backend-system/core-services/scheduler.md b/docs/backend-system/core-services/scheduler.md index 154878ddfc..eb25692698 100644 --- a/docs/backend-system/core-services/scheduler.md +++ b/docs/backend-system/core-services/scheduler.md @@ -38,3 +38,94 @@ createBackendPlugin({ }, }); ``` + +## REST API + +The scheduler exposes a REST API on top of each plugin's base URL, that lets you inspect and affect the current state of all of that plugin's tasks. + +### `GET /.backstage/scheduler/v1/tasks` + +Lists all tasks that the given plugin registered at startup, and their current states. The response shape is as follows: + +```json +{ + "tasks": [ + { + "taskId": "InternalOpenApiDocumentationProvider:refresh", + "pluginId": "catalog", + "scope": "global", + "settings": { + "version": 2, + "cadence": "PT10S", + "initialDelayDuration": "PT10S", + "timeoutAfterDuration": "PT1M" + }, + "taskState": { + "status": "idle", + "startsAt": "2025-04-11T20:35:13.418+02:00", + "lastRunEndedAt": "2025-04-11T20:35:03.453+02:00" + }, + "workerState": { + "status": "initial-wait" + } + } + ] +} +``` + +Each task has the following properties: + +| Field | Format | Description | +| ------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `taskId` | string | A unique (per plugin) ID for the task | +| `pluginId` | string | The plugin where the task is scheduled | +| `scope` | string | Either `local` (runs on each worker node with potential overlaps, similar to `setInterval`), or `global` (runs on one worker node at a time, without overlaps) | +| `settings` | object | Serialized form of the initial settings passed in when scheduling the task. The only completely fixed well known field is `version`; the others depend on what version is used | +| `settings.version` | string | Internal identifier of the format of the settings object. The format of this object can change completely for each version. This document describes version 2 specifically | +| `settings.cadence` | string; ISO duration | How often the task runs. Either the string `manual` (only runs when manually triggered), or an ISO duration string starting with the letter P, or a `cron` format string | +| `settings.initialDelayDuration` | string; ISO duration | How long workers wait at service startup before starting to look for work, to give the service some time to stabilize, as an ISO duration string (if configured) | +| `settings.timeoutAfterDuration` | string; ISO duration | How long after a task starts that it's considered timed out and available for retries | +| `taskState` | object | The current state of the task (see below for details) | +| `workerState` | object | The status of the worker responsible for task | + +The `taskState` shape depends on whether the task is currently running or not. When running: + +| Field | Format | Optional | Description | +| -------------------------- | ----------------------------- | -------- | ------------------------------------------------------------------------- | +| `taskState.status` | string | | `running` | +| `taskState.startedAt` | string; ISO timestamp | | When the current task run started | +| `taskState.timesOutAt` | string; ISO timestamp | | When the current task run will time out if it does not finish before that | +| `taskState.lastRunError` | string; JSON serialized error | optional | When the task last ran, if it threw an error, this field contains it | +| `taskState.lastRunEndedAt` | string; ISO timestamp | optional | When the task last ran, it ended at this time | + +When the task is idle: + +| Field | Format | Optional | Description | +| -------------------------- | ----------------------------- | -------- | ------------------------------------------------------------------------------------------ | +| `taskState.status` | string | | `idle` | +| `taskState.startsAt` | string; ISO timestamp | optional | When the task is scheduled to run next; will not be set if the task uses manual scheduling | +| `taskState.lastRunError` | string; JSON serialized error | optional | When the task last ran, if it threw an error, this field contains it | +| `taskState.lastRunEndedAt` | string; ISO timestamp | optional | When the task last ran, it ended at this time | + +The `workerState` shape is as follows: + +| Field | Description | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `workerState.status` | The status of the worker responsible for task; either `initial-wait` (right at service startup), `running` (task is currently running), or `idle` (task is not running at the moment) | + +### `POST /.backstage/scheduler/v1/tasks//trigger` + +Schedules the given task ID for immediate execution, instead of waiting for its +next scheduled time slot to arrive. + +Note that there can still be an additional small delay before a worker discovers +that the task is due and actually picks it up. This typically takes less than a +second, but it can vary. + +The request has no body. + +Responds with + +- `200 OK` if successful +- `404 Not Found` if there was no such registered task for this plugin +- `409 Conflict` if the task was already in a running state