3

I am setting up a job scheduler using Agenda.js and Node, backed with MongoDB. So far it's working as expected. However, I'm unclear how to schedule a repeating job -- for instance, a job that should run every day at 9am.

"schedule" is used for a one-time scheduling of a job, but not repeats:

agenda.schedule('today at 09:00am CST', 'first job');

"every" works with an interval like "3 minutes", but not with "day at 9:00am"

agenda.every('3 minutes', 'second job');

Since configuration methods are supposedly chainable I also tried this:

agenda.processEvery('24 hours').schedule('day at 09:45am CST', 'second job');

... this did run the task successfully the first time 9:45am CST arrived, but it didn't reset it to run the next day at the same time.

What syntax would I use to run a job EVERY day at 9:00am? And, even better, how can I schedule that to run on Monday - Friday only?

Rey
  • 1,393
  • 1
  • 15
  • 24

4 Answers4

4

Ajenda accepts cron format. So you can do something like this

This is repeat Job At 09:00 on every day-of-week from Monday through Friday

job.repeatEvery('0 9 * * 1-5', {
    skipImmediate: true
});

SkipImmediate is Optional. Here is CRON checker for above cron string. Read more about repeatEvery

EDIT

Job is returned when Agenda is made

agenda.define('NAME', async job => {
            job.repeatEvery('0 9 * * 1-5', {
                skipImmediate: true
            });
            await job.save()
        }

Read more about Creating Jobs

Shivam
  • 3,514
  • 2
  • 13
  • 27
  • Thanks, but I get an `agenda.repeatEvery is not a function` error when I try this. – Rey Oct 10 '19 at 14:05
  • This is what I tried: `agenda.repeatEvery('* 9 * * 1-5', { skipImmediate: true });` – Rey Oct 10 '19 at 14:06
  • Yes because `repeatEvery` is available on `job` not `agenda`. `Job` is what `agenda` returns – Shivam Oct 10 '19 at 14:07
  • Right. And would one need to chain on a `save()` to get this to persist to the database? What would that look like? – Rey Oct 10 '19 at 14:22
  • Yup you got the Idea! Read about it [here](https://github.com/agenda/agenda#createjobname-data) – Shivam Oct 10 '19 at 14:23
0

I had a similar use case, but I did not want to use a cron string.

const agendaEvery = async (interval, sendTime, name, data, options) => {
  const job = agenda
    .create(name, data)
    .repeatEvery(interval, {
      timezone: 'Asia/Kuala_Lumpur',
      skipImmediate: true,
      startDate: sendTime
    })
    .schedule(sendTime)
  await job.save()
}

This will allow say you want to send a daily email, you can use a ISO formatted datetime string to schedule the first one, and the interval can be for .e.g 1 day.

  • Great solution. I'm not clear on how to incorporate it with the agenda.every because they require (interval, name, data, options)? So if I do – Marco Aug 07 '22 at 13:03
0

Using skipImmediate: true with repeatEvery, I got a typescript error. The line

agenda.every('0 9 * * 1-5', cronTypes.PUSH, null, {skipImmediate: true});

worked

Gyl
  • 61
  • 6
0

The approved solution seems a bit funky. I feel calling job.repeatEvery() within the job handler is kind of out of its place.

agenda.every accepts cron format, therefore you can apply it to any defined job and run the handler according to the cron sequence

You have a defined job:

agenda.define('do-something', async (job, done) => {
  // Doing some heavy async stuff here
  async heavyStuff();
  done();
})

After server initialisation you can call it anywhere in your code to setup a repeated job. Just make sure await agenda.start() was already called and agenda has an established mongo connection

await agenda.every("0 9 * * 1-5", "do-something");
sznrbrt
  • 993
  • 2
  • 11
  • 32