143 lines
5.1 KiB
JavaScript
143 lines
5.1 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.InlineScheduledTask = void 0;
|
|
const events_1 = __importDefault(require("events"));
|
|
const runner_1 = require("../scheduler/runner");
|
|
const time_matcher_1 = require("../time/time-matcher");
|
|
const create_id_1 = require("../create-id");
|
|
const state_machine_1 = require("./state-machine");
|
|
const logger_1 = __importDefault(require("../logger"));
|
|
const localized_time_1 = require("../time/localized-time");
|
|
class TaskEmitter extends events_1.default {
|
|
}
|
|
class InlineScheduledTask {
|
|
emitter;
|
|
cronExpression;
|
|
timeMatcher;
|
|
runner;
|
|
id;
|
|
name;
|
|
stateMachine;
|
|
timezone;
|
|
constructor(cronExpression, taskFn, options) {
|
|
this.emitter = new TaskEmitter();
|
|
this.cronExpression = cronExpression;
|
|
this.id = (0, create_id_1.createID)('task', 12);
|
|
this.name = options?.name || this.id;
|
|
this.timezone = options?.timezone;
|
|
this.timeMatcher = new time_matcher_1.TimeMatcher(cronExpression, options?.timezone);
|
|
this.stateMachine = new state_machine_1.StateMachine();
|
|
const runnerOptions = {
|
|
timezone: options?.timezone,
|
|
noOverlap: options?.noOverlap,
|
|
maxExecutions: options?.maxExecutions,
|
|
beforeRun: (date, execution) => {
|
|
if (execution.reason === 'scheduled') {
|
|
this.changeState('running');
|
|
}
|
|
this.emitter.emit('execution:started', this.createContext(date, execution));
|
|
return true;
|
|
},
|
|
onFinished: (date, execution) => {
|
|
if (execution.reason === 'scheduled') {
|
|
this.changeState('idle');
|
|
}
|
|
this.emitter.emit('execution:finished', this.createContext(date, execution));
|
|
return true;
|
|
},
|
|
onError: (date, error, execution) => {
|
|
logger_1.default.error(error);
|
|
this.emitter.emit('execution:failed', this.createContext(date, execution));
|
|
this.changeState('idle');
|
|
},
|
|
onOverlap: (date) => {
|
|
this.emitter.emit('execution:overlap', this.createContext(date));
|
|
},
|
|
onMissedExecution: (date) => {
|
|
this.emitter.emit('execution:missed', this.createContext(date));
|
|
},
|
|
onMaxExecutions: (date) => {
|
|
this.emitter.emit('execution:maxReached', this.createContext(date));
|
|
this.destroy();
|
|
}
|
|
};
|
|
this.runner = new runner_1.Runner(this.timeMatcher, (date, execution) => {
|
|
return taskFn(this.createContext(date, execution));
|
|
}, runnerOptions);
|
|
}
|
|
getNextRun() {
|
|
if (this.stateMachine.state !== 'stopped') {
|
|
return this.runner.nextRun();
|
|
}
|
|
return null;
|
|
}
|
|
changeState(state) {
|
|
if (this.runner.isStarted()) {
|
|
this.stateMachine.changeState(state);
|
|
}
|
|
}
|
|
start() {
|
|
if (this.runner.isStopped()) {
|
|
this.runner.start();
|
|
this.stateMachine.changeState('idle');
|
|
this.emitter.emit('task:started', this.createContext(new Date()));
|
|
}
|
|
}
|
|
stop() {
|
|
if (this.runner.isStarted()) {
|
|
this.runner.stop();
|
|
this.stateMachine.changeState('stopped');
|
|
this.emitter.emit('task:stopped', this.createContext(new Date()));
|
|
}
|
|
}
|
|
getStatus() {
|
|
return this.stateMachine.state;
|
|
}
|
|
destroy() {
|
|
if (this.stateMachine.state === 'destroyed')
|
|
return;
|
|
this.stop();
|
|
this.stateMachine.changeState('destroyed');
|
|
this.emitter.emit('task:destroyed', this.createContext(new Date()));
|
|
}
|
|
execute() {
|
|
return new Promise((resolve, reject) => {
|
|
const onFail = (context) => {
|
|
this.off('execution:finished', onFail);
|
|
reject(context.execution?.error);
|
|
};
|
|
const onFinished = (context) => {
|
|
this.off('execution:failed', onFail);
|
|
resolve(context.execution?.result);
|
|
};
|
|
this.once('execution:finished', onFinished);
|
|
this.once('execution:failed', onFail);
|
|
this.runner.execute();
|
|
});
|
|
}
|
|
on(event, fun) {
|
|
this.emitter.on(event, fun);
|
|
}
|
|
off(event, fun) {
|
|
this.emitter.off(event, fun);
|
|
}
|
|
once(event, fun) {
|
|
this.emitter.once(event, fun);
|
|
}
|
|
createContext(executionDate, execution) {
|
|
const localTime = new localized_time_1.LocalizedTime(executionDate, this.timezone);
|
|
const ctx = {
|
|
date: localTime.toDate(),
|
|
dateLocalIso: localTime.toISO(),
|
|
triggeredAt: new Date(),
|
|
task: this,
|
|
execution: execution
|
|
};
|
|
return ctx;
|
|
}
|
|
}
|
|
exports.InlineScheduledTask = InlineScheduledTask;
|
|
//# sourceMappingURL=inline-scheduled-task.js.map
|