user2885234
user2885234

Reputation: 11

Can Quartz scheduler refire broken job at application shutdown?

I have an application with a few different, long running quartz jobs. Every job is triggered by a kind of event (for example user action) and it is intended to run only once per such an event. In the environment where the application works the following scenario happens...

  1. Application is running,
  2. Long running job is triggered,
  3. During the execution of the job application shutdown occurs,
  4. Application is starded again.

Is it possible to cause that quartz will automatically refire the job started and not finished previously (in the previous session of the application)? I mean using jdbc job store, which works well for misfired jobs - but is it possible to refire not finished job.

Upvotes: 1

Views: 1067

Answers (1)

Turin
Turin

Reputation: 175

This is the best approach I've found:

  1. Configure quartz scheduler with:

    org.quartz.scheduler.interruptJobsOnShutdownWithWait=true

  2. Make your recoverable jobs implementing InterruptableJob, and manually trigger the current job as part of interrupt logic (example below).
  3. Write your own ShutdownHook to call Scheduler.shutdown(true) or use quartz ShutdownHookPlugin

This way, when an ordered shutdown is detected by the VM (hard shutdowns bust be handled by RequestRecovery: quartz jobDetail requestRecovery), jobs implementing InterruptableJob will be interrupted and re-triggered. This trigger will not occur until next start.

There is a quick example of how to implement:

public static class TriggerOnInterruptJob implements InterruptableJob {
    private boolean interrupt = false;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LOGGER.debug("START");
        synchronized (mutex) {
            mutex.notifyAll();
        }
        executionCount.incrementAndGet();
        try {
            while (!interrupt)
                Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            context.getScheduler().triggerJob(context.getJobDetail().getKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void interrupt() throws UnableToInterruptJobException {
        interrupt = true;

    }

}

Upvotes: 1

Related Questions