diff --git a/src/lib/features/startup-tasks/startup-task-service.ts b/src/lib/features/startup-tasks/startup-task-service.ts new file mode 100644 index 0000000000..23c225756b --- /dev/null +++ b/src/lib/features/startup-tasks/startup-task-service.ts @@ -0,0 +1,66 @@ +import { Logger, LogProvider } from '../../logger'; +import { IMaintenanceStatus } from '../maintenance/maintenance-service'; + +export interface IStartupTask { + shouldRun(): Promise; + run(): Promise; + stop(): Promise; +} + +interface IScheduledTask { + timeout: NodeJS.Timeout; + task: IStartupTask; + id: string; +} + +export class StartupTaskService { + private tasks: Map = new Map(); + + private logger: Logger; + + private maintenanceStatus: IMaintenanceStatus; + + constructor(getLogger: LogProvider, maintenanceStatus: IMaintenanceStatus) { + this.logger = getLogger('/services/startup-task-service.ts'); + this.maintenanceStatus = maintenanceStatus; + } + + async scheduleStart( + scheduledTask: IStartupTask, + timeMs: number, + id: string, + ): Promise { + this.logger.info('Scheduling startup task'); + + if (!scheduledTask.shouldRun()) { + this.logger.info('Startup task not needed'); + return; + } + + const timeoutRef = setTimeout(async () => { + try { + const maintenanceMode = + await this.maintenanceStatus.isMaintenanceMode(); + if (!maintenanceMode) { + if (!scheduledTask.shouldRun()) { + this.logger.info('Startup task not needed'); + return; + } + await scheduledTask.run(); + this.logger.info('Startup task completed'); + } + } catch (e) { + this.logger.error(`scheduled task failed | id: ${id} | ${e}`); + } + }, timeMs).unref(); + + this.tasks.set(id, { timeout: timeoutRef, task: scheduledTask, id }); + } + + stop(): void { + this.tasks.forEach((item) => { + clearTimeout(item.timeout); + item.task.stop(); + }); + } +}