From 1578276708a6a036e736ef7c42f273fe94220e1d Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Wed, 22 Feb 2023 12:46:22 +0200 Subject: [PATCH] feat: add functionality to get scheduled tasks add new functionality to PluginTaskScheduler to return local and global tasks. this is to be able to trigger those tasks manually using the triggerTask functionality when there's no clear way to figure out the correct id to use as they in many cases come from a plugin. this is also usable for the upcoming debug plugin, see #9737 Signed-off-by: Heikki Hellgren --- .changeset/fresh-hairs-switch.md | 5 +++ packages/backend-tasks/api-report.md | 5 +++ .../src/tasks/PluginTaskSchedulerImpl.test.ts | 41 +++++++++++++++++++ .../src/tasks/PluginTaskSchedulerImpl.ts | 8 ++++ packages/backend-tasks/src/tasks/index.ts | 1 + packages/backend-tasks/src/tasks/types.ts | 21 ++++++++++ 6 files changed, 81 insertions(+) create mode 100644 .changeset/fresh-hairs-switch.md diff --git a/.changeset/fresh-hairs-switch.md b/.changeset/fresh-hairs-switch.md new file mode 100644 index 0000000000..16d3b119e5 --- /dev/null +++ b/.changeset/fresh-hairs-switch.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-tasks': minor +--- + +add functionality to get descriptions from the scheduler for triggering diff --git a/packages/backend-tasks/api-report.md b/packages/backend-tasks/api-report.md index 44ec4addbe..66f901adad 100644 --- a/packages/backend-tasks/api-report.md +++ b/packages/backend-tasks/api-report.md @@ -16,6 +16,7 @@ export type HumanDuration = HumanDuration_2; // @public export interface PluginTaskScheduler { createScheduledTaskRunner(schedule: TaskScheduleDefinition): TaskRunner; + getScheduledTasks(): TaskDescriptor[]; scheduleTask( task: TaskScheduleDefinition & TaskInvocationDefinition, ): Promise; @@ -27,6 +28,10 @@ export function readTaskScheduleDefinitionFromConfig( config: Config, ): TaskScheduleDefinition; +// @public +export type TaskDescriptor = TaskScheduleDefinition & + Exclude; + // @public export type TaskFunction = | ((abortSignal: AbortSignal) => void | Promise) diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts index 1847370d2b..d64f353c27 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts @@ -304,6 +304,47 @@ describe('PluginTaskManagerImpl', () => { ); }); + describe('can fetch task ids', () => { + it.each(databases.eachSupportedId())( + 'can fetch both global and local task ids, %p', + async databaseId => { + const { manager } = await init(databaseId); + + const fn = jest.fn(); + const promise = new Promise(resolve => fn.mockImplementation(resolve)); + await manager.scheduleTask({ + id: 'task1', + timeout: Duration.fromMillis(5000), + frequency: Duration.fromMillis(5000), + fn, + scope: 'global', + }); + + await manager.scheduleTask({ + id: 'task2', + timeout: Duration.fromMillis(5000), + frequency: Duration.fromMillis(5000), + fn, + scope: 'local', + }); + + await promise; + + const tasks = manager.getScheduledTasks(); + expect(tasks.length).toEqual(2); + expect(tasks[0].id).toEqual('task1'); + expect(tasks[1].id).toEqual('task2'); + expect(tasks[0].scope).toEqual('global'); + expect(tasks[1].scope).toEqual('local'); + expect(tasks[0].fn).toBeUndefined(); + expect(tasks[1].fn).toBeUndefined(); + expect(tasks[0].signal).toBeUndefined(); + expect(tasks[1].signal).toBeUndefined(); + }, + 60_000, + ); + }); + describe('parseDuration', () => { it('should parse durations', () => { expect(parseDuration({ milliseconds: 5000 })).toEqual('PT5S'); diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts index e57ec93c1c..bbc2b45718 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts @@ -21,6 +21,7 @@ import { LocalTaskWorker } from './LocalTaskWorker'; import { TaskWorker } from './TaskWorker'; import { PluginTaskScheduler, + TaskDescriptor, TaskInvocationDefinition, TaskRunner, TaskScheduleDefinition, @@ -32,6 +33,7 @@ import { validateId } from './util'; */ export class PluginTaskSchedulerImpl implements PluginTaskScheduler { private readonly localTasksById = new Map(); + private readonly allScheduledTasks: TaskDescriptor[] = []; constructor( private readonly databaseFactory: () => Promise, @@ -94,6 +96,8 @@ export class PluginTaskSchedulerImpl implements PluginTaskScheduler { this.localTasksById.set(task.id, worker); } + const { fn: _, signal: __, ...descriptor } = task; + this.allScheduledTasks.push(descriptor as TaskDescriptor); } createScheduledTaskRunner(schedule: TaskScheduleDefinition): TaskRunner { @@ -103,6 +107,10 @@ export class PluginTaskSchedulerImpl implements PluginTaskScheduler { }, }; } + + getScheduledTasks(): TaskDescriptor[] { + return this.allScheduledTasks; + } } export function parseDuration( diff --git a/packages/backend-tasks/src/tasks/index.ts b/packages/backend-tasks/src/tasks/index.ts index f2037ac9dd..6f9ac6d859 100644 --- a/packages/backend-tasks/src/tasks/index.ts +++ b/packages/backend-tasks/src/tasks/index.ts @@ -19,6 +19,7 @@ export { TaskScheduler } from './TaskScheduler'; export type { PluginTaskScheduler, TaskFunction, + TaskDescriptor, TaskInvocationDefinition, TaskRunner, TaskScheduleDefinition, diff --git a/packages/backend-tasks/src/tasks/types.ts b/packages/backend-tasks/src/tasks/types.ts index 6ec5165aec..d8aa58bcb3 100644 --- a/packages/backend-tasks/src/tasks/types.ts +++ b/packages/backend-tasks/src/tasks/types.ts @@ -31,6 +31,14 @@ export type TaskFunction = | ((abortSignal: AbortSignal) => void | Promise) | (() => void | Promise); +/** + * A type to describe a scheduled task. + * + * @public + */ +export type TaskDescriptor = TaskScheduleDefinition & + Exclude; + /** * Options that control the scheduling of a task. * @@ -307,6 +315,19 @@ export interface PluginTaskScheduler { * @param schedule - The task schedule */ createScheduledTaskRunner(schedule: TaskScheduleDefinition): TaskRunner; + + /** + * Returns all scheduled tasks registered to this scheduler. + * + * @remarks + * + * This method is useful for triggering tasks manually using the triggerTask + * functionality. Note that the returned tasks contain only tasks that have + * been initialized in this instance of the scheduler. + * + * @returns Scheduled tasks + */ + getScheduledTasks(): TaskDescriptor[]; } function isValidOptionalDurationString(d: string | undefined): boolean {