Java – make waiting Quartz Jobs fire in the order they were triggered

javaquartz-scheduler

I have an application using the Quartz Scheduler to schedule jobs. The application is currently running Quartz version 1.6.2. My JobStore is org.quartz.impl.jdbcjobstore.JobStoreTX with an Oracle database backing it. Clustering is turned on, but there's only one scheduler using the database. My Quartz threadPool is configured as follows:

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5

My jobs are long running, so it's fairly common to have 5 jobs running (the maximum allowed by my thead pool) when triggers fire new jobs. The newly triggered jobs misfire and I see log messages like the following:

2011-05-20 04:09:30,097 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:08:29 05/20/2011
2011-05-20 04:09:30,120 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:09:30 05/20/2011
2011-05-20 04:09:30,125 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:08:30 05/20/2011
2011-05-20 04:09:30,138 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:09:30 05/20/2011
2011-05-20 04:11:29,998 INFO  [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time.

Once a running job finishes, one of the misfired jobs will get picked up and run normally. However, Quartz seems to pick up a misfired job randomly, with no regard to the order the jobs had been originally scheduled to execute. Ideally, I'd like them to be picked up in the order they were supposed to have run, based on their original fire times.

Is it possible to make my waiting (misfired) jobs get fired in the order they were triggered once space in the Quartz ThreadPool becomes available?

Best Answer

When quartz handles a trigger that has missed it's fire time it will update the nextFireTime of the trigger. By default a trigger will be considered missed if it's nextFireTime is over 60 seconds in the past. Missed triggers should still be selected based on nextFireTime and priority order but I'm guessing it seems random because some triggers have been updated and others haven't.

I would suggest increasing the org.quartz.jobStore.misfireThreshold property. See http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore.html (although the property is identical for all JobStores). This should make it less likely for your triggers to be re-scheduled.

Related Topic