Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to kill a current running Quartz Job?

I remember that we cannot kill the current running Quartz Job but we can interrupt and have a boolean check wherever is necessary whether we need to proceed further with the subsequent operations or not.

Even when we implement the InterruptableJob and call the scheduler.interrupt to interrupt the Job, the current executed job will be still running in the server.

Ex:

  1. A named SQL query has been triggered by the job via Hibernate which takes a long time
  2. A call has been made to a third party server where the third party server takes a long time to respond

http://neopatel.blogspot.in/2011/05/quartz-stop-job.html http://forums.terracotta.org/forums/posts/list/3191.page

Could someone corrects my understanding and explain me how we can kill or stop the "currently" executing Job ?

like image 647
Kathir Avatar asked Oct 26 '12 05:10

Kathir


3 Answers

you can create new abstract class called JobBase for example that implements IJob interface and insert abstract method: public abstract void ExecuteJob(IJobExecutionContext context);

On JobBase you can implements method Execute like this

public abstract class JobBase : IJob,IInterruptableJob
{
     private Thread currentThread;
     private ILog logger;
     public JobBase(ILog logger)
     {
        this.logger=logger;
     }
        public void Execute(IJobExecutionContext context)
        {

            var thread = new Thread(()=> 
            {
                try
                {
                    this.ExecuteJob(context);
                }
                catch(Exception ex)
                {
                    this.logger.ErrorFormat("Unhandled exception {0}",ex.ToString());

                }
            });

            thread.Start();
            this.currentThread = thread;
            this.currentThread.Join();  
        }
        public abstract void ExecuteJob(IJobExecutionContext context);

        public void Interrupt()
        {   
            currentThread.Abort();
        }
}

Each Job will implements JobExecute method.

  public class TestJob :JobBase
{
    private ILog logger;
    public TeJob(ILog logger):base(logger)
    {
    }

    public override ExecuteJob(IJobExecutionContext context)
    {
    }
}

Assumes that use some factory for creating a Job

For Stopping a Job you will call method scheduler.Interrupt(new JobKey(jobName));

like image 79
Alessandro Cunsolo Avatar answered Oct 24 '22 06:10

Alessandro Cunsolo


As you told, there is no way to interrupt "brutally" a job in quartz, neither in JAVA.

You can encapsulate your job's logic in a separate Thread and run it with the ExecutorService.

Take a look to this example: https://stackoverflow.com/a/2275596/1517816

Assume your QuartzJob is the Test class and move your business logic in the Task class.

Hope it helps

like image 36
poussma Avatar answered Oct 24 '22 06:10

poussma


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. :)

like image 2
Nikhil Kumar Avatar answered Oct 24 '22 06:10

Nikhil Kumar