Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quartz recovering from multiple days misfire

I'm trying to set up Quartz for the first time, and forgive me if I am just not understanding something. I'm wondering what is the best way to accomplish the following:

How to set up a job that must run a daily email report, and also be able to recover from a missed trigger so that: 1) the job knows what day the trigger was SUPPOSED to fire on. and 2) if (god forbid) the server is down for 3 days, Quartz will recover by running three missed days consecutively, also informing the job of what day each job represents. (execution order is not really important as long as I know what day each represents)

Right now I am just doing:

Trigger trigger = newTrigger() 
.withIdentity("dailyTrigger", "scheduledReportEmail") 
.startNow() 
.withSchedule(dailyAtHourAndMinute(0, 5) .withMisfireHandlingInstructionFireAndProceed()) 
.build(); 

This only seems to recover by running once, no matter how many days get missed. Is that correct?

One approach I thought about is basically setting up 31 daily triggers, for days 1-31. Clunky.. and what might happen in February for those extra days? Is this the best approach?

I've also got weekly and monthly triggers to deal with but I figure if we're down for three weeks then we have bigger things to worry about :)

thanks for any advice....

like image 717
Eric M Avatar asked Dec 27 '22 11:12

Eric M


1 Answers

Your use case is pretty standard and supported by Quartz. You just need "ignore misfires" policy:

Trigger trigger = newTrigger() 
  .withIdentity("dailyTrigger", "scheduledReportEmail") 
  .withSchedule(dailyAtHourAndMinute(0, 5)
  .withMisfireHandlingInstructionIgnoreMisfires()) 
  .build(); 

This basically means: I don't care that the trigger(s) misfired, just run it as soon as possible (that is most likely at application startup).

To figure out when given trigger was suppose to run (what was the scheduled time as opposed to current time), run this in your job:

void execute(JobExecutionContext context) {
  final Date scheduled = context.getScheduledFireTime()
  //...
}

See also

  • difference between last actual and scheduled fire time
  • issue when using quartz withMisfireHandlingInstructionIgnoreMisfires
  • Quartz scheduler misfire instructions explained - my article describing various misfire instructions
like image 178
Tomasz Nurkiewicz Avatar answered Jan 14 '23 02:01

Tomasz Nurkiewicz