@stouder-io/adonis-scheduler
Version:
Unopinionated scheduler for Adonis
85 lines (84 loc) • 2.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Scheduler = void 0;
const cron_parser_1 = require("cron-parser");
const sourceFiles_1 = require("./utils/sourceFiles");
class Scheduler {
constructor(logger, app) {
this.logger = logger;
this.app = app;
this.tasks = new Map();
}
async loadTasks() {
const files = await (0, sourceFiles_1.sourceFiles)(this.app.appRoot, this.app.resolveNamespaceDirectory('tasks') || './app/Tasks');
for (const file of files) {
const task = new (file.getTask())();
if (this.tasks.has(task.name)) {
this.logger.error(`task ${task.name} already exists`);
continue;
}
const cronExpression = (0, cron_parser_1.parseExpression)(task.cron);
this.tasks.set(task.name, {
cron: cronExpression,
nextRunAt: cronExpression.next(),
task,
});
}
}
nextTask() {
let foundEntry = null;
for (const [name, cachedTask] of this.tasks) {
if (foundEntry === null ||
cachedTask.nextRunAt.getTime() < foundEntry[1].nextRunAt.getTime()) {
foundEntry = [name, cachedTask];
}
}
if (foundEntry === null) {
this.logger.warn('no next task found, scheduler stopped.');
return null;
}
return foundEntry;
}
async wakeUp() {
// run every old tasks
const tasksToUpdate = [];
for (const [name, cachedTask] of this.tasks) {
if (cachedTask.nextRunAt.getTime() <= Date.now()) {
try {
await cachedTask.task.run();
}
catch (error) {
this.logger.error(`task ${name} failed: ${error.message}`);
}
tasksToUpdate.push(name);
}
}
for (const taskToUpdate of tasksToUpdate) {
const cachedTask = this.tasks.get(taskToUpdate);
if (cachedTask === undefined) {
this.logger.error(`task ${taskToUpdate} not found`);
continue;
}
cachedTask.nextRunAt = cachedTask.cron.next();
}
// pick next task
const nextTask = this.nextTask();
if (nextTask === null) {
return;
}
// set timeout
setTimeout(() => {
this.wakeUp();
}, nextTask[1].nextRunAt.getTime() - Date.now());
}
async start() {
const nextTask = this.nextTask();
if (nextTask === null) {
return;
}
setTimeout(() => {
this.wakeUp();
}, nextTask[1].nextRunAt.getTime() - Date.now());
}
}
exports.Scheduler = Scheduler;