pdmq
Version:
158 lines (157 loc) • 8.27 kB
JavaScript
;
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;