UNPKG

wakaq

Version:

Background task queue for Node backed by Redis, a super minimal Celery

68 lines (67 loc) 3.53 kB
"use strict"; 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;