wakaq
Version:
Background task queue for Node backed by Redis, a super minimal Celery
68 lines (67 loc) • 3.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WakaQScheduler = void 0;
const ts_duration_1 = require("ts-duration");
const exceptions_js_1 = require("./exceptions.js");
const logger_js_1 = require("./logger.js");
class WakaQScheduler {
constructor(wakaq) {
this.wakaq = wakaq;
this.logger = (0, logger_js_1.setupLogging)(this.wakaq, false, true);
this.wakaq.logger = this.logger;
}
async start() {
this.logger.info(`scheduler_log_file=${this.wakaq.schedulerLogFile}`);
this.logger.info(`scheduler_log_level=${this.wakaq.schedulerLogLevel}`);
this.logger.info(`num_scheduled_tasks=${this.wakaq.schedules.length}`);
this.logger.info(`default_queue=${this.wakaq.defaultQueue.name}`);
if (this.wakaq.schedules.length == 0) {
this.logger.error('no scheduled tasks found');
throw new exceptions_js_1.WakaQError('No scheduled tasks found.');
}
this.wakaq.schedules.forEach((task) => {
this.logger.info(`scheduled task "${task.taskName}" with schedule ${task.schedule}`);
});
this.logger.info('scheduler started');
let upcomingTasks = [];
try {
await this.wakaq.connect();
while (true) {
const now = new Date();
this.logger.debug(`Iteration at ${now.toISOString()}`);
this.logger.debug(`Number upcoming tasks this iteration: ${upcomingTasks.length}`);
await Promise.all(upcomingTasks.map(async (cronTask) => {
const task = this.wakaq.tasks.get(cronTask.taskName);
if (!task) {
this.logger.warn(`task not found, maybe treeshaking removed it: ${cronTask.taskName}`);
}
const queue = cronTask.queue ?? task?.queue ?? this.wakaq.defaultQueue;
this.logger.debug(`run scheduled task on queue ${queue.name}: ${cronTask.taskName}`);
await this.wakaq.enqueueAtFront(cronTask.taskName, cronTask.args, queue);
}));
const crons = this.wakaq.schedules.map((cronTask) => {
cronTask.interval.reset(now);
return { duration: ts_duration_1.Duration.millisecond(Math.abs(cronTask.interval.next().getTime() - now.getTime())), cronTask: cronTask };
});
this.logger.debug(`Deciding how long to sleep from ${crons.length} tasks.`);
const sleepDuration = crons
.map((cron) => cron.duration)
.reduce((prev, next) => {
this.logger.debug(`Comparing previous ${prev.milliseconds} to ${next.milliseconds}`);
return next.milliseconds < prev.milliseconds ? next : prev;
}, ts_duration_1.Duration.hour(24));
upcomingTasks = crons.filter((cron) => cron.duration.milliseconds <= sleepDuration.milliseconds).map((cron) => cron.cronTask);
const sleepUntil = new Date(Date.now() + sleepDuration.milliseconds);
this.logger.debug(`Sleeping for ${sleepDuration.minutes} minutes until ${sleepUntil.toISOString()}`);
await this.wakaq.sleep(sleepDuration);
}
}
catch (error) {
this.logger.error(error);
}
finally {
this.wakaq.disconnect();
}
}
}
exports.WakaQScheduler = WakaQScheduler;