UNPKG

pdmq

Version:
158 lines (157 loc) 8.27 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskService = void 0; const task_trigger_types_enum_1 = require("../../enums/task-trigger-types.enum"); const moment = require("moment"); const uuid_1 = require("uuid"); class TaskService { constructor() { } /** * Calculate Next Run Time * * @param task * @returns {string} YYYY:MM:DD:HH:mm:ss */ getNextRunTime(task) { /** For tasks only run for once */ if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.ONCE) { return moment(task.task_trigger_once_datetime).format("YYYY:MM:DD:HH:mm:ss"); } /** For tasks run every day */ else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.DAILY) { const momentTime = moment(moment().format("YYYY-MM-DD ") + task.task_trigger_time, "YYYY-MM-DD HH:mm:ss"); const valid = momentTime.isAfter(moment()); if (valid) return momentTime.format("YYYY:MM:DD:HH:mm:ss"); else return moment().add(1, 'day').format("YYYY:MM:DD:") + task.task_trigger_time; } /** For tasks run weekly */ else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.WEEKLY) { const ISODay = Number(moment().format('E')); const todate = moment().format("YYYY:MM:DD:"); for (const day of task.task_trigger_days) { /** Skip if day already passed */ if (day < ISODay) continue; /** Return if today is after ISO day */ else if (day > ISODay) return moment().add(day - ISODay, 'day').format(`YYYY:MM:DD:${task.task_trigger_time}`); /** Return if days are same but time is after now */ else if (day == ISODay && moment(todate + task.task_trigger_time, "YYYY:MM:DD:HH:mm:ss", true).isAfter(moment())) return moment().format("YYYY:MM:DD:") + task.task_trigger_time; } /** Return the first day of next week */ return moment().add(1, 'week').startOf('week').add(task.task_trigger_days[0], 'day') .format(`YYYY:MM:DD:${task.task_trigger_time}`); } else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.MONTHLY) { const momentTime = moment(moment().format(`YYYY-MM-${task.task_trigger_date} ${task.task_trigger_time}`), "YYYY-MM-DD HH:mm:ss"); const valid = momentTime.isAfter(moment()); if (valid) return momentTime.format("YYYY:MM:DD:HH:mm:ss"); else return moment().add(1, 'month').format(`YYYY:MM:${task.task_trigger_date}:${task.task_trigger_time}`); } else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.ANNUALLY) { for (const month of task.task_trigger_months) { const momentTime = moment(moment().format(`YYYY-${month}-${task.task_trigger_date} ${task.task_trigger_time}`), "YYYY-MM-DD HH:mm:ss"); const valid = momentTime.isAfter(moment()); if (valid) return momentTime.format("YYYY:MM:DD:HH:mm:ss"); } return moment().add(1, 'year') .format(`YYYY:${task.task_trigger_months[0]}:${task.task_trigger_date}:${task.task_trigger_time}`); } } /** * Verify Task Is Valid * * @param task */ verifyTask(task) { var _a, _b; if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.ONCE) return moment(task.task_trigger_once_datetime).isValid() && moment(task.task_trigger_once_datetime).isAfter() ? true : 'Invalid value in task_trigger_once_datetime'; else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.INSTANT || task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.NEVER) return true; else if (!task.task_trigger_time) return 'Attribute task_trigger_time can not be empty'; else if (!moment(task.task_trigger_time, 'HH:mm:ss', true).isValid()) return 'Invalid value in task_trigger_time'; else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.WEEKLY) return ((_a = task.task_trigger_days) === null || _a === void 0 ? void 0 : _a.length) ? true : 'Attribute task_trigger_days cannot be empty'; else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.MONTHLY) return task.task_trigger_date ? true : 'Attribute task_trigger_date cannot be empty'; else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.ANNUALLY) { if (!task.task_trigger_date) return 'Attribute task_trigger_date cannot be empty'; else if (!((_b = task.task_trigger_months) === null || _b === void 0 ? void 0 : _b.length)) return 'Attribute task_trigger_months cannot be empty'; } return true; } /** * * @param storedTaskId * @param redisService * @returns {PDMQTask} New Instant Task */ runStoredTask(storedTaskId, redisService) { return __awaiter(this, void 0, void 0, function* () { const [taskString] = yield redisService.getMulti([`tasks:${task_trigger_types_enum_1.TaskTriggerTypes.NEVER}:${storedTaskId}`]); if (!taskString) throw "Stored Task Not Found"; const task = JSON.parse(taskString); task.task_trigger_type = task_trigger_types_enum_1.TaskTriggerTypes.INSTANT; const newInstantTask = yield this.addTask(task, redisService); return newInstantTask; }); } /** * Add task to queue * * @param task PDMQ Task * @returns {PDMQTask} New Task */ addTask(task, redisService) { return __awaiter(this, void 0, void 0, function* () { const isValidTask = this.verifyTask(task); if (typeof isValidTask == 'string') throw isValidTask; if (!task.task_id) { task.task_id = uuid_1.v1(); task.task_created_at = moment().toISOString(); } else { task.task_updated_at = moment().toISOString(); } if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.NEVER) { yield redisService.set(`tasks:${task.task_trigger_type}:${task.task_id}`, JSON.stringify(task)); } else if (task.task_trigger_type === task_trigger_types_enum_1.TaskTriggerTypes.INSTANT) { yield redisService.setWithIndex(`tasks:${task.task_trigger_type}:${new Date().getTime()}:${task.task_id}`, JSON.stringify(task), task_trigger_types_enum_1.TaskTriggerTypes.INSTANT, 0); } else { const timeKey = this.getNextRunTime(task); task.trigger_next_at = moment(timeKey, "YYYY:MM:DD:HH:mm:ss", true).toISOString(); if (!timeKey) throw `Unexpected error, unable to get next run time for the task`; yield redisService.set(`tasks:${timeKey}:${task.task_id}`, JSON.stringify(task)); } return task; }); } } exports.TaskService = TaskService;