@kitmi/jacaranda
Version:
JavaScript application framework
187 lines (186 loc) • 6.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
cronPatterns: function() {
return cronPatterns;
},
default: function() {
return _default;
}
});
const _utils = require("@kitmi/utils");
const _types = require("@kitmi/types");
const _worker = /*#__PURE__*/ _interop_require_default(require("./worker"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const cronPatterns = {
EVERY_SECOND: 'every-second',
EVERY_MINUTE: 'every-minute',
EVERY_HOUR: 'every-hour',
EVERY_DAY: 'every-day',
EVERY_WEEK: 'every-week',
EVERY_MONTH: 'every-month',
BY_DATE: 'by-day'
};
/**
* Convert the schedule pattern to cron format.
* @param {object} nodeSchedule
* @param {object} cronInfo
* @returns {array} [rule, description]
*/ const toCronFormat = (nodeSchedule, { pattern, perUnit, day, hour, minute, second, tz, date })=>{
perUnit = perUnit != null ? (0, _utils.toInteger)(perUnit) : 0;
switch(pattern){
case cronPatterns.EVERY_SECOND:
if (perUnit > 0) {
return [
`*/${perUnit} * * * * *`,
`every ${perUnit} seconds`
];
} else {
return [
'* * * * * *',
'every second'
];
}
case cronPatterns.EVERY_MINUTE:
if (perUnit > 0) {
return [
`${second ?? 0} */${perUnit} * * * *`,
`every ${perUnit} minutes`
];
} else {
const rule = new nodeSchedule.RecurrenceRule();
rule.second = second ?? 0;
if (tz) rule.tz = tz;
return [
rule,
'every minute'
];
}
case cronPatterns.EVERY_HOUR:
if (perUnit > 0) {
return [
`${second ?? 0} ${minute ?? 0} */${perUnit} * * *`,
'every ${perUnit} hours'
];
} else {
const rule = new nodeSchedule.RecurrenceRule();
rule.second = second ?? 0;
rule.minute = minute ?? 0;
if (tz) rule.tz = tz;
return [
rule,
'every hour'
];
}
case cronPatterns.EVERY_DAY:
if (perUnit > 0) {
return [
`${second ?? 0} ${minute ?? 0} ${hour ?? 0} */${perUnit} * *`,
`every ${perUnit} days`
];
} else {
const rule = new nodeSchedule.RecurrenceRule();
rule.second = second ?? 0;
rule.minute = minute ?? 0;
rule.hour = hour ?? 0;
if (tz) rule.tz = tz;
return [
rule,
'every day'
];
}
case cronPatterns.EVERY_MONTH:
if (perUnit > 0) {
return [
`${second ?? 0} ${minute ?? 0} ${hour ?? 0} ${day ?? 0} */${perUnit} *`,
`every ${perUnit} month`
];
} else {
const rule = new nodeSchedule.RecurrenceRule();
rule.second = second ?? 0;
rule.minute = minute ?? 0;
rule.hour = hour ?? 0;
// rule.day = day ?? 1;
rule.date = day ?? 1;
if (tz) rule.tz = tz;
return [
rule,
'every month'
];
}
case cronPatterns.BY_DATE:
if (!date || !(date instanceof Date)) {
throw new Error('Invalid date.');
}
return [
date,
'on specified date: ' + date.toISOString()
];
default:
throw new Error('To be implemented.');
}
};
/**
*
* @param {Function} worker
* @param {object} options
*/ async function startScheduler(schedules, jobs, options) {
const workerOptions = {
throwOnError: true,
dontStop: true,
...options
};
if (!Array.isArray(schedules)) {
throw new _types.InvalidArgument('Invalid schedules.');
}
if (!(0, _utils.isPlainObject)(jobs)) {
throw new _types.InvalidArgument('Invalid jobs.');
}
const scheduledJobs = {};
return (0, _worker.default)(async (app)=>{
const nodeSchedule = await app.tryRequire_('node-schedule', true);
app.on('stopping', async ()=>{
// eslint-disable-next-line no-undef
nodeSchedule.gracefulShutdown().catch((error)=>console.error(error.message || error));
});
const counters = _utils._.mapValues(jobs, ()=>0);
schedules.forEach((schedule)=>{
const [cron, desc] = toCronFormat(nodeSchedule, schedule);
const job = schedule.job;
app.log('info', `Scheduled to execute job [${job}] ${desc}`);
const fnJob = jobs[job];
if (fnJob == null) {
throw new _types.InvalidArgument(`Job [${job}] not found.`, {
schedule
});
}
const reportInterval = schedule.reportInterval ?? 1;
scheduledJobs[job] = nodeSchedule.scheduleJob(cron, function() {
let asyncCall = job === '_report-schedules' ? fnJob(app, schedules, scheduledJobs) : fnJob(app);
asyncCall.then(()=>{
const completed = ++counters[job];
if (completed % reportInterval === 0) {
app.log('info', `Job [${job}] has been executed for ${completed} time(s).`);
}
}).catch((error)=>{
app.logError(error);
});
});
});
return app;
}, workerOptions);
}
const _default = startScheduler;
//# sourceMappingURL=schedulerWorker.js.map