[Code Dump] Meteor cron job script


#1

Hey all,

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();
  }
});

#2

Thanks for posting.

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.

Thanks


#3

You can check out synced cron if you are trying to sync jobs across servers?


#4

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.


#5

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?


#6

Ahh, I gotcha. I suppose I hadn’t gotten that far yet with multiple servers. :wink: 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!