I have created a sample program using quartz. Where the main program will trigger a controller job which runs every 3 seconds and from this controller I have scheduled a job to run in a cron schedule.
My requirement is that if one instance of the job is running then the next instance should not start. So I have iterated over the list of jobcontext from scheduler context currently active jobs and make a check if any instance of the job matching to current job instance exists then simply return.
To test this I have implemented a thread sleep in the respective jobs which is more than the scheduled time. The job instances are not getting fired in parallel which is expected, but my scheduler context currently active job list is increasing continuously. I need a help in reducing/keep check on the size of the current active jobs.
My program is as below.
Main program:
package com.test.objectpool;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class CronTriggerExample {
public static void main(String[] args) throws Exception {
JobDetail job = JobBuilder.newJob(QuartzSchedulerController.class).withIdentity("job-a-cntrl", "group.12-1")
.build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger.1", "group.12-1")
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()).build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
}
}
Controller job:
package com.test.objectpool;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
public class QuartzSchedulerController implements Job {
public void execute(JobExecutionContext context) {
try {
context.getScheduler().getCurrentlyExecutingJobs().forEach(job -> {
if (job.getTrigger().equals(context.getTrigger()) && !job.getJobInstance().equals(this)) {
System.out.println("There's another instance running crontroller , so leaving" + this);
return;
}
});
Thread.sleep(4000);
System.out.println("Inside scheduler controller --- >> ");
Scheduler scheduler = context.getScheduler();
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("hello-1.1", "group1-1.2").build();
JobKey jbK = job.getKey();
System.out.println("Job key is " + jbK);
if (!scheduler.checkExists(jbK)) {
System.out.println("Scheduling hellow world -----");
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger.1", "group1-1.2").withSchedule(
CronScheduleBuilder.cronSchedule("0/2 * * * * ?").withMisfireHandlingInstructionDoNothing())
.build();
scheduler.scheduleJob(job, trigger);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
And finally the job class that is controlled by controller is:
package com.test.objectpool;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
public class HelloJob implements Job {
private static int count = 0;
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
List<JobExecutionContext> jobs = context.getScheduler().getCurrentlyExecutingJobs();
System.out.println("The size of the job queue is " + jobs.size());
for (JobExecutionContext job : jobs) {
if (job.getTrigger().equals(context.getTrigger()) && !job.getJobInstance().equals(this)) {
System.out.println("There's another instance running, so leaving" + this);
return;
}
}
Date dt = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
String uniqueID = UUID.randomUUID().toString();
System.out.println("Hello Quartz!" + context.getScheduledFireTime() + " :With count " + count
+ " :Current date " + sdf.format(dt) + " UUID =" + uniqueID);
Thread.sleep(10000);
// System.out.println("Hello Quartz!"+
// context.getScheduledFireTime());
System.out.println("Completed " + "With count " + count + " UUID : " + uniqueID);
count++;
} catch (SchedulerException | InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
The issue is that with this approach the context.getScheduler().getCurrentlyExecutingJobs() keeps on increasing.