This is something I’ve had in my toolbox for awhile - just wanted to share it with everyone else in case anyone has a need for it.
cron.js (server-side only)
import { Meteor } from 'meteor/meteor';
import parser from 'cron-parser'; // npm package
function getMsFromNow(job) {
return job.iterator.next().getTime() - Date.now();
}
// Example job
const jobs = [
{
name: 'Do something',
cronExpression: '0 */4 * * *',
runAtStartup: false,
func() { /* your code here */ },
},
];
Meteor.startup(function () {
for (const job of jobs) {
job.iterator = parser.parseExpression(job.cronExpression);
const executionDelay = getMsFromNow(job);
/*
* Make a function that will run the func, figure out the next execution
* time, then call func at that time
*/
job.execFunc = (delay) => {
Meteor.setTimeout(() => {
console.log('### Executing cron job:', job.name);
job.func();
job.execFunc(getMsFromNow(job));
}, delay);
};
job.execFunc(executionDelay);
if (job.runAtStartup) job.func();
}
});
How are you handling jobs if you have a pool of (redundant) app servers running the same app? We’ve been exploring a few strategies so that jobs are completed by instances with less traffic/utilization and also never duplicated since they are unique jobs, or only need to be completed once every five minutes etc.
I’m using Galaxy and mLab (considering moving to Compose), so everything is already handled as far as replication. If the cron job modifies the database, it’s replicated everywhere automatically and instantly.
Ok nice, I guess I meant more about not repeating jobs once you start to activate more instances in galaxy. I saw you were only using one instance from another thread, so maybe that hasn’t been an issue yet?
Ahh, I gotcha. I suppose I hadn’t gotten that far yet with multiple servers. The immediate solution that comes to mind is tracking cron job execution via the database. I guess that’s version 2 for down the road!