How to interrupt or stop currently running quartz job?
Asked Answered
S

6

24

I have some tasks that are executed with the help of Java Quartz Jobs, but I need to stop some tasks by some condition in my code. I read that this can be done via InterruptableJob. But i didn't understand in what way i should do it?

Smithy answered 23/8, 2011 at 9:45 Comment(0)
S
39

You need to write your job as an implementation of InterruptableJob. To interrupt this job, you need handle to Scheduler , and call interrupt(jobKey<<job name & job group>>)

Please have a look @ javadoc for above classes, also quartz distribution contains an example for this (example7).

Siderosis answered 23/8, 2011 at 10:36 Comment(1)
The limitation of this approach is not cluster aware. Java doc: This method is not cluster aware. That is, it will only interrupt instances of the identified InterruptableJob currently executing in this Scheduler instance, not across the entire cluster.Acanthoid
O
5

In Quartz 2.1 with Spring you can:

@Autowired
private Scheduler schedulerFactoryBean; //injected by spring
...
...

List<JobExecutionContext> currentlyExecuting = schedulerFactoryBean.getCurrentlyExecutingJobs();

//verifying if job is running       
for (JobExecutionContext jobExecutionContext : currentlyExecuting) {
    if(jobExecutionContext.getJobDetail().getKey().getName().equals("JobKeyNameToInterrupt")){
        result = schedulerFactoryBean.interrupt(jobExecutionContext.getJobDetail().getKey());
    }
}
Ordonez answered 25/6, 2013 at 14:1 Comment(0)
S
2

Probably a little late to answer this, but may be it can help:

If you no longer need a job, you can delete that particular job using

scheduler.deleteJob(jobKey(<JobKey>, <JobGroup>));

This method will only interrupt/stop the job uniquely identified by the Job Key and Group within the scheduler which may have many other jobs running.

On the other hand if you want to completely shutdown the scheduler and all the jobs therein you can do

scheduler.shutdown();

This is a pretty nice example of different job related tasks.

Sponge answered 18/3, 2019 at 17:39 Comment(0)
C
1

The best solution in my opinion is the one described in this thread: http://forums.terracotta.org/forums/posts/list/7700.page

I've just introduced a "sleep" after set stop flag to true to allow the job to finish cleanly.

    @Override
public void interrupt() throws UnableToInterruptJobException {
    stopFlag.set(true);
    try {
        Thread.sleep(30000);
    } catch (InterruptedException e) {
        //logger.error("interrupt()", e);
    }
    Thread thread = runningThread.getAndSet(null);
    if (thread != null)
        thread.interrupt();
}
Catenate answered 2/11, 2014 at 10:36 Comment(0)
N
1

I don't know why nobody mentioned this, or maybe this was not available at the time the question was asked.

There is a method called shutdown for a Scheduler instance.

 SchedulerFactory factory = new StdSchedulerFactor();
 Scheduler scheduler = factory.getScheduler();

The above is used to start a job like

 scheduler.start();

Use a flag or something to know when to stop the job from running. Then use

 scheduler.shutdown();

How I implemented my requirement:

if(flag==true)
    {
        scheduler.start();
        scheduler.scheduleJob(jobDetail, simpleTrigger);
    }
    else if(flag==false)
    {
        scheduler.shutdown();
    }

Where jobDetail and simpleTrigger are self explanatory.

Hope it helps. :)

Nolita answered 21/5, 2015 at 15:27 Comment(2)
This solution is shutting down the whole scheduler which is not really correct unless you have one job assigned to the scheduler. You should have a way to remove only specific job not the whole scheduler because it is possible to have more than one job running on the same scheduler.Diarmid
Having more than one job on a Scheduler? I would even say it's extremely common, and shutting down the Scheduler would be a disaster in that case.Larianna
D
0

To interrupt all running jobs

for (JobExecutionContext currentlyExecutingJob : scheduler.getCurrentlyExecutingJobs()) {
    if (InterruptableJob.class.isAssignableFrom(currentlyExecutingJob.getJobDetail().getJobClass())) // Otherwise it will throw an exception
        scheduler.interrupt(currentlyExecutingJob.getFireInstanceId());
}

You can get jobs informations in JobExecutionContext, retrieve the Job class or things like that.

Dominiquedominium answered 6/4, 2021 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.