[Logo] Terracotta Discussion Forums (LEGACY READ-ONLY ARCHIVE)
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
[Expert]
Recovering job after interrupt  XML
Forum Index -> Quartz
Author Message
thrykol

neo

Joined: 04/29/2014 07:00:01
Messages: 5
Offline

It is my understanding that if a trigger is created with requestRecovery set to true, then when the job is interrupted either via a container restart (tomcat in my case) or Scheduler.interrupt(jobKey) then the job should be rescheduled according to the misfire instruction.

In my application I am creating a trigger via TriggerBuilder.newTrigger using the smart policy. The job also has requestRecovery set to true. As such, when the job is interrupted via a container restart or manually via Scheduler.interrupt(jobKey) it is my expectation that the job should be rescheduled for immediate refire. This does not happen.

Is my expectation incorrect or is there something else I need to configure? I am using Quartz 2.2.1 via Maven central. My properties file has org.quartz.scheduler.interruptJobsOnShutdownWithWait set to 'true' and in the case of container shutdown, I am telling the scheduler to wait on shutdown.

Any help or clarification would be greatly appreciated.
adahanne

master

Joined: 03/20/2012 23:14:46
Messages: 95
Offline

hello,
yes if your job is interrupted and you request receovery, the next time you start your app you should see a recovering trigger firing your job.
Are you using quartz connected to a database ?
thrykol

neo

Joined: 04/29/2014 07:00:01
Messages: 5
Offline

I am using a database. The following is the equivalent of my quartz.properties file


org.quartz.scheduler.skipUpdateCheck=true
org.quartz.scheduler.instanceName=SchedulerContext
org.quartz.scheduler.interruptJobsOnShutdownWithWait=true
org.quartz.threadPool.threadCount=12
org.quartz.dataSource.quartz.jndiURL=java:comp/env/jdbc/MY_DATABASE
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.dataSource=quartz
 


I have checked qrtz_job_details.requests_recovery to verify that the job is indeed marked as recoverable. Is there another column somewhere in the database that indicates the job needs to be recovered?
thrykol

neo

Joined: 04/29/2014 07:00:01
Messages: 5
Offline

I took a look at the code for QuartzScheduler.interrupt(). It appears all that code does is call the InterruptableJob.interrupt() method (after verifying the job is interruptable). Does my job need to do something besides return cleanly from the execute method to inform the scheduler it was interrupted?
adahanne

master

Joined: 03/20/2012 23:14:46
Messages: 95
Offline

Hello,
I could make recovery work with this code :

Code:
JobDetail job1 = newJob(MyJob.class).requestRecovery().withIdentity("job1", "group1").build();


and a similar quartz configuration.
Quartz will try to recover jobs that did not complete, take this as an example :
Code:
public void execute(JobExecutionContext context)
       throws JobExecutionException {
 
     if (context.isRecovering()) {
       System.err.println("Job tried to recover !");
       _log.info("My thread is :" + Thread.currentThread().getName());
     }
     _log.info("Get ready to die");
     if (shouldDie()) {
       try {
         Runtime.getRuntime().halt(255);
       } catch (Exception e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
       }
     }
   }
thrykol

neo

Joined: 04/29/2014 07:00:01
Messages: 5
Offline

Thanks for the input. Based on your code sample, I now believe my understanding of how recovery works was incorrect. Using this code:

Code:
 public void execute(final JobExecutionContext context)
 {
 	if(context.isRecovering()) {
 		log.info("Job tried to recover !");
 		log.info("My thread is :" + Thread.currentThread().getName());
 	}
 
 	while(! this.interrupted) {
 		Thread.sleep(1000); // Removed try/catch for clarity
 	}
 
 	log.info("Job cleanly interrupted");
 }
 
within a tomcat instance, calling
Code:
kill -9 <TOMCAT_PID>
results in a RECOVERING_JOBS trigger for the job. However, calling
Code:
tomcat stop
or
Code:
scheduler.interrupt(jobKey)
there is not a RECOVERING_JOBS trigger for the job.

I would like reload my context while a job which is interruptable and recoverable is running. Is this possible such that the job will exit pre-maturely (via a handled interrupt) when the context is destroyed and then recover (ie restarted) once the context is re-initialized? I could write a scheduler shutdown hook such that the jobs are interrupted and rescheduled in the future but would like a baked in solution if possible.
 
Forum Index -> Quartz
Go to:   
Powered by JForum 2.1.7 © JForum Team