@whook/whook
Version:
Build strong and efficient REST web services.
70 lines • 3.22 kB
JavaScript
import cron from 'node-cron';
import { autoProvider, location } from 'knifecycle';
import { printStackTrace } from 'yerror';
export const DEFAULT_CRON_RUNNER_OPTIONS = {
timezone: 'UTC',
};
async function initLocalCronRunner({ APP_ENV, CRON_RUNNER_OPTIONS = DEFAULT_CRON_RUNNER_OPTIONS, CRONS_HANDLERS, CRONS_DEFINITIONS, log, }) {
const cronsNames = Object.keys(CRONS_DEFINITIONS);
const tasks = {};
log('warning', `⌚ - Initializing the local cron runner (${cronsNames.length} crons).`);
for (const cronName of cronsNames) {
let index = 0;
for (const schedule of CRONS_DEFINITIONS[cronName].module.definition
.schedules) {
const taskName = `${cronName}-${index++}`;
const promises = [];
if (schedule.environments !== 'all' ||
!schedule.environments.includes(APP_ENV)) {
log('debug', `⏳ - Skipped "${cronName}" crons schedule "${schedule.rule}" since not enabled in environment "${APP_ENV}".`);
continue;
}
log('debug', `⌚ - Scheduling the "${cronName}" cron with "${schedule.rule}" (task name: "${taskName}").`);
const task = cron.schedule(schedule.rule, () => {
const promise = (async () => {
log('debug', `⌚ - Running the "${cronName}" cron with "${schedule.rule}" (task name: "${taskName}").`);
try {
// Run handler here and await
await CRONS_HANDLERS[cronName]({
date: new Date().toISOString(),
body: schedule.body,
}, CRONS_DEFINITIONS[cronName].module.definition);
log('debug', `✅ - Successfully ran the "${cronName}" cron with "${schedule.rule}" (task name: "${taskName}").`);
}
catch (err) {
log('error', `❌ - The "${cronName}" cron produced an error.`);
log('error-stack', printStackTrace(err));
}
await Promise.resolve().then(() => {
promises.splice(promises.indexOf(promise), 1);
});
})();
promises.push(promise);
}, {
name: taskName,
...CRON_RUNNER_OPTIONS,
});
tasks[taskName] = {
task,
promises,
};
task.start();
}
}
return {
service: undefined,
dispose: async () => {
let runningCrons = 0;
for (const taskName of Object.keys(tasks)) {
tasks[taskName].task.stop();
runningCrons += tasks[taskName].promises.length;
}
log('warning', `⌚ - Stopping the local cron runner (${runningCrons} crons running).`);
for (const taskName of Object.keys(tasks)) {
await Promise.all(tasks[taskName].promises);
}
},
};
}
export default location(autoProvider(initLocalCronRunner), import.meta.url);
//# sourceMappingURL=localCronRunner.js.map