From 739de82471ca887a2cf92ecde7da68f6e2bdf955 Mon Sep 17 00:00:00 2001 From: Bogdan Nechyporenko Date: Sat, 14 Oct 2023 18:58:50 +0200 Subject: [PATCH] Made shut down stale tasks configurable. Signed-off-by: Bogdan Nechyporenko --- .changeset/pink-eyes-reflect.md | 5 +++ app-config.yaml | 8 ----- plugins/scaffolder-backend/config.d.ts | 20 +++++++++++ .../scaffolder-backend/src/service/router.ts | 33 ++++++++++++------- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/.changeset/pink-eyes-reflect.md b/.changeset/pink-eyes-reflect.md index 1b2a82e508..b6e9f7f2b5 100644 --- a/.changeset/pink-eyes-reflect.md +++ b/.changeset/pink-eyes-reflect.md @@ -3,3 +3,8 @@ --- Made shut down stale tasks configurable. + +There are two properties exposed: + +- `scaffolder.processingInterval` - sets the processing interval for staled tasks. +- `scaffolder.taskTimeout` - sets the task's heartbeat timeout, when to consider a task to be staled. diff --git a/app-config.yaml b/app-config.yaml index 8e2b176985..c53a6475f4 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -304,14 +304,6 @@ scaffolder: # email: scaffolder@backstage.io # Use to customize the default commit message when new components are created # defaultCommitMessage: 'Initial commit' - # - # Use to run check on stale tasks every minute. By default, it is '*/5 * * * *', what means to run every 5 minutes. - # staleTasks: - # cron: * * * * * - # - # Use to consider the task stale when no task heartbeat during 2 minutes. By default, it is 24 hours. - # staleTasks: - # timeout: 120 # seconds auth: ### Add auth.keyStore.provider to more granularly control how to store JWK data when running diff --git a/plugins/scaffolder-backend/config.d.ts b/plugins/scaffolder-backend/config.d.ts index 60ccd52257..9d3fc1716d 100644 --- a/plugins/scaffolder-backend/config.d.ts +++ b/plugins/scaffolder-backend/config.d.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { HumanDuration } from '@backstage/types'; + export interface Config { /** Configuration options for the scaffolder plugin */ scaffolder?: { @@ -37,5 +39,23 @@ export interface Config { * Set to 0 to disable task workers altogether. */ concurrentTasksLimit?: number; + + /** + * Sets the processing interval for staled tasks. + * + * Staled tasks are marked as failed, once task's timeout has exceeded. + * + * By default, processing interval is every 5 minutes. + */ + processingInterval: HumanDuration; + + /** + * Sets the task's heartbeat timeout, when to consider a task to be staled. + * + * Once task is considered to be staled, the scheduler will shut it down on the next cycle. + * + * Default value is 24 hours. + */ + taskTimeout?: HumanDuration; }; } diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index a76b47fad2..c51540f2ec 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -24,10 +24,10 @@ import { stringifyEntityRef, UserEntity, } from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; +import { Config, readDurationFromConfig } from '@backstage/config'; import { InputError, NotFoundError, stringifyError } from '@backstage/errors'; import { ScmIntegrations } from '@backstage/integration'; -import { JsonObject, JsonValue } from '@backstage/types'; +import { HumanDuration, JsonObject, JsonValue } from '@backstage/types'; import { TaskSpec, TemplateEntityV1beta3, @@ -77,6 +77,7 @@ import { PermissionRule, } from '@backstage/plugin-permission-node'; import { scaffolderActionRules, scaffolderTemplateRules } from './rules'; +import { Duration } from 'luxon'; /** * @@ -215,6 +216,17 @@ function buildDefaultIdentityClient(options: RouterOptions): IdentityApi { }; } +const readDuration = ( + config: Config, + key: string, + defaultValue: HumanDuration, +) => { + if (config.has(key)) { + return readDurationFromConfig(config, { key }); + } + return defaultValue; +}; + /** * A method to create a router for the scaffolder backend plugin. * @public @@ -259,18 +271,17 @@ export async function createRouter( if (scheduler && databaseTaskStore.listStaleTasks) { await scheduler.scheduleTask({ id: 'close_stale_tasks', - frequency: { - cron: - options.config.getOptionalString('scaffolder.staleTasks.cron') ?? - '*/5 * * * *', - }, // every 5 minutes, also supports Duration + frequency: readDuration(config, 'scaffolder.processingInterval', { + minutes: 5, + }), timeout: { minutes: 15 }, fn: async () => { const { tasks } = await databaseTaskStore.listStaleTasks({ - timeoutS: - options.config.getOptionalNumber( - 'scaffolder.staleTasks.timeout', - ) ?? 86400, + timeoutS: Duration.fromObject( + readDuration(config, 'scaffolder.taskTimeout', { + seconds: 86400, + }), + ).as('seconds'), }); for (const task of tasks) {