import { ScheduleData, Timer } from '../../types/helpers/later-overrides'; import { ILogger } from '../../../types'; export interface ScheduleConfig { /** * defaultPerTaskConcurrency * The idea behind this property is to control how many of the same task can run at the same time. * For example, * If you have a task that is scheduled every second but it takes 10 seconds to complete * then you might have 10 of the same task running at the same time * This may be ok or you may only want 1 single instance of any task to run at the same time. **/ defaultPerTaskConcurrency?: number; /** * defaultMaxPerTaskQueueLength * The way task managment works is by using a queue. This controls how large the task queue can be. * If a task interval goes off while an existing task is running and concurrency is already limited * then your task queue may grow. * This variable controls the max length of that queue **/ defaultMaxPerTaskQueueLength?: number; timezoneConfig?: 'local' | 'utc'; tasks: TaskConfig[]; } export interface TaskConfig { name: string; /** * The way task managment works is by using a queue. This controls how large the task queue can be. * If a task interval goes off while an existing task is running and concurrency is already limited * then your task queue may grow. * This variable controls the max length of that queue * This controls the max queue length for the current task whereas the top level defaultMaxPerTaskQueueLength controls the default value **/ maxTaskQueueLength?: number | null; /** * The idea behind this property is to control how many of the same task can run at the same time. * For example, * If you have a task that is scheduled every second but it takes 10 seconds to complete * then you might have 10 of the same task running at the same time * This may be ok or you may only want 1 single instance of any task to run at the same time. * This controls the concurrency limit for this task whereas the top level defaultPerTaskConcurrency controls the default value **/ concurrency?: number | null; intervalText?: string | null; intervalCron?: string | null; input?: any; } export interface Task { name: string; maxTaskQueueLength: number; concurrency: number; promiseQueue?: any; schedule: ScheduleData; taskConfig: TaskConfig; handle?: Timer | null; input?: any; } export default class TaskScheduler { private logger?; private schedulerConfig; private taskList; private isStarted; private scheduledFn; /** * Constructor for the TaskScheduler * @param {logger, schedulerConfig} - a logger so this class can log * @constructor */ constructor({ logger, schedulerConfig, scheduledFn, }: { logger?: ILogger; schedulerConfig: ScheduleConfig; scheduledFn: (task: Task) => any; }); /** * start - This must be called before the tasks actually start running * * @params none * return undefined **/ start(): void; /** * stop - This is called to stop the scheduler * * @params none * return undefined **/ stop(): void; /** * Schedule a task - This should be called from the start function and not externally * Does this by calling an interval timer using the later.js library * * @params task - Object with the task config (name/schedule/taskFn/skipIfBackup) * return undefined **/ private _scheduleTask; /** * Add to the task's promise queue * * @params task - Object with the task config (name/schedule/taskFn/skipIfBackup/promiseQueue) ***/ private _addToTaskQueue; /** * This function is intended for internal use only. * It takes a task config from conf/task-scheduler.json * * @params taskConfig - Object with task name and schedule config * and file with class that has a static execute funciton * return undefined - Or throws error if it fails ***/ private _addToInternalTaskList; }