Agenda: How to run job at certain time and then repeat after that time.

Created on 26 Oct 2015  路  6Comments  路  Source: agenda/agenda

This is what I want to do in human terms:

I want to schedule a job to run exactly once at 6pm today and then every day after that at 6pm.

But I cannot seem to find a combination of .schedule(), .repeatAt(), or .every() that works like this.

.every() and .repeatAt() both run on server startup and don't take a "begin to repeat" date, so each time my server restarts I run the job.

Am I missing something?

Most helpful comment

Ah yes, that helped a lot. So here is what I ended up doing, if it helps anyone else:

Reminders.SMS.Agenda.define('send a text reminder', function (job, done) {
  const text = job.attrs.data.text;
  Nexmo.sendTextMessage(text.sender, text.recipient, text.message, text.opts, function (err, result) {
    if (_.isDate(job.attrs.data.end) && job.attrs.nextRunAt > job.attrs.data.end) {
      job.remove(done);
    }
    done(err, result);
  });
});

Reminders.SMS.scheduleRecurring = function (userId, options) {
  let data = this._getTextOptions(userId, options);
  let job = this.Agenda.create('send a text reminder', data);
  job.schedule(options.start);        // start at this time
  job.repeatAt(options.repeatAt);  // repeat at this time
  job.save();                                  // good to go
}

All 6 comments

Just use every with the cron notation:
agenda.every('0 18 * * *', 'job-definition-that-will-run-everyday-at-6pm');
For more information: http://www.nncron.ru/help/EN/working/cron-format.htm

Came here for the same reason. I want to start a cron at some arbitrary time. Here is the use case.

Orders.after('update', function (doc) {
  if (doc.status === 'ready') {
    const start = doc.schedule.start;  // don't start the cron until this time
    const end = doc.schedule.end;    // purge the cron when past this date.
    Scheduler.every('* 8,18 * * *', 'send a reminder', doc); 
  }
});

@AlexFrazer, I would do that at the job-level:

Orders.after('update', function (doc) {
  if (doc.status === 'ready') {
    Scheduler.every('* 8,18 * * *', 'send a reminder', doc); 
  }
});

agenda.define('send a reminder', function (job, done) {
  const doc = job.attrs.data;
  const start = doc.schedule.start;
  const end = doc.schedule.end;
  // Here you can return prematurely if now < start, remove job from db if now > end and process otherwise
  // ...
});

yeah, I think that this works, although I can't find a good way to delete the job after end date other than to start a new job that deletes all the old ones at a certain time.

Can鈥檛 check right now, but using job.remove inside the job definition should work:

agenda.define('send a reminder', function (job, done) {
  ...
  job.remove(function(err) {
    if(!err) console.log("Successfully removed job from collection");
  })
});

Ah yes, that helped a lot. So here is what I ended up doing, if it helps anyone else:

Reminders.SMS.Agenda.define('send a text reminder', function (job, done) {
  const text = job.attrs.data.text;
  Nexmo.sendTextMessage(text.sender, text.recipient, text.message, text.opts, function (err, result) {
    if (_.isDate(job.attrs.data.end) && job.attrs.nextRunAt > job.attrs.data.end) {
      job.remove(done);
    }
    done(err, result);
  });
});

Reminders.SMS.scheduleRecurring = function (userId, options) {
  let data = this._getTextOptions(userId, options);
  let job = this.Agenda.create('send a text reminder', data);
  job.schedule(options.start);        // start at this time
  job.repeatAt(options.repeatAt);  // repeat at this time
  job.save();                                  // good to go
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

nhan-pt picture nhan-pt  路  4Comments

ruslanjur picture ruslanjur  路  4Comments

mavvverick picture mavvverick  路  3Comments

niftylettuce picture niftylettuce  路  6Comments

ekegodigital picture ekegodigital  路  3Comments