| 50 | const DEFAULT_COORDINATOR_TTL = 30000; |
| 51 | |
| 52 | export class Runner { |
| 53 | timeMatcher: TimeMatcher; |
| 54 | onMatch: OnMatch; |
| 55 | noOverlap: boolean; |
| 56 | maxExecutions?: number; |
| 57 | maxRandomDelay: number; |
| 58 | missedExecutionTolerance: number; |
| 59 | runCount: number; |
| 60 | |
| 61 | running: boolean; |
| 62 | |
| 63 | heartBeatTimeout?: NodeJS.Timeout; |
| 64 | logger: Logger; |
| 65 | onMissedExecution: OnFn; |
| 66 | onOverlap: OnFn; |
| 67 | onError: OnErrorHookFn; |
| 68 | beforeRun: OnHookFn; |
| 69 | onFinished: OnHookFn; |
| 70 | onMaxExecutions: OnFn; |
| 71 | |
| 72 | runCoordinator?: RunCoordinator; |
| 73 | coordinatorKeyPrefix: string; |
| 74 | coordinatorTtl: number; |
| 75 | onSkipped: OnSkippedFn; |
| 76 | |
| 77 | constructor(timeMatcher: TimeMatcher, onMatch: OnMatch, options?: RunnerOptions){ |
| 78 | this.timeMatcher = timeMatcher; |
| 79 | this.onMatch = onMatch; |
| 80 | this.noOverlap = options == undefined || options.noOverlap === undefined ? false : options.noOverlap; |
| 81 | this.maxExecutions = options?.maxExecutions; |
| 82 | this.maxRandomDelay = options?.maxRandomDelay || 0; |
| 83 | this.missedExecutionTolerance = options?.missedExecutionTolerance ?? DEFAULT_MISSED_EXECUTION_TOLERANCE; |
| 84 | this.logger = options?.logger || logger; |
| 85 | |
| 86 | this.onMissedExecution = options?.onMissedExecution || emptyOnFn; |
| 87 | this.onOverlap = options?.onOverlap || emptyOnFn; |
| 88 | |
| 89 | this.onError = options?.onError || ((date: Date, error: Error) => this.logger.error('Task failed with error!', error)); |
| 90 | this.onFinished = options?.onFinished || emptyHookFn; |
| 91 | this.beforeRun = options?.beforeRun || emptyHookFn; |
| 92 | |
| 93 | this.onMaxExecutions = options?.onMaxExecutions || emptyOnFn; |
| 94 | |
| 95 | this.runCoordinator = options?.runCoordinator; |
| 96 | this.coordinatorKeyPrefix = options?.coordinatorKeyPrefix || ''; |
| 97 | this.coordinatorTtl = options?.coordinatorTtl ?? DEFAULT_COORDINATOR_TTL; |
| 98 | this.onSkipped = options?.onSkipped || emptySkipFn; |
| 99 | |
| 100 | this.runCount = 0; |
| 101 | this.running = false; |
| 102 | } |
| 103 | |
| 104 | private onErrorFallback = (date: Date, error: Error) => { |
| 105 | this.logger.error('Task failed with error!', error); |
| 106 | } |
| 107 | |
| 108 | /** |
| 109 | * Runs `run` under the run coordinator when one is configured. If the |