UNPKG

@kitmi/jacaranda

Version:

JavaScript application framework

187 lines (186 loc) 6.36 kB
"use strict"; 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