Quartz jobs - disallow concurrent execution group-wide?

╄→尐↘猪︶ㄣ 提交于 2019-12-06 14:34:57

its has been a long time since I used quartz, however I would try two job listeners registered to listen to two different groups

the basic idea is to have one job fire from a group / list ("todayGroup"), the '("todayGroup") job listener detects the completion for good or bad. then kicks off the next job in the list. However, it saves the 'just finished' job back in the scheduler under the ("tomorrowGroup").

public class MyTodayGroupListener extends JobListenerSupport {

    private String name;

    private static String GROUP_NAME = "todayGroup";

    public MyOtherJobListener(String name) {
    this.name = name;
    }

    public String getName() {
    return name;
    }


    @Override
    public void jobWasExecuted(JobExecutionContext context,
        JobExecutionException jobException) {
        Scheduler sched = context.getScheduler();
        // switch the job to the other group so we don't run it again today.
        JobDetail current = context.getJobDetail();
        JobDetail tomorrows  = current.getJobBuilder().withIdentity(current.getKey().getName(), "tomorrow").build();
        sched.addJob(tomorrows,true);

        //see if there is anything left to run
        Set<JobKey> jobKeys = sched.getJobKeys(groupEquals(GROUP_NAME ));
        Iterator<JobKey> nextJob = null;
        if(jobKeys != null && !jobKeys.isEmpty() ){
            nextJob = jobKeys.iterator();
        }
        if(nextJob != null){
            // Define a Trigger that will fire "now" and associate it with the first job from the list
            Trigger trigger = newTrigger()
                .withIdentity("trigger1", "group1")
                .startNow()
                .forJob(nextJob =.next())
                .build();

            // Schedule the trigger
            sched.scheduleJob(trigger);
        }

    }
}

likewise, you'll need two 'group triggers' that will fire the first job from their respective groups at the given time you want.

The Trigger Listener class below should re-schedule any jobs that attempt to execute while another job that the listener has been configured for is running. Ive only lightly tested it but for simple cases it should be suitable.

public class SequentialTriggerListener extends TriggerListenerSupport {

private JobKey activeJob;
private Scheduler activeScheduler;
private Queue<JobDetail> queuedJobs = new ConcurrentLinkedQueue<JobDetail>();

public String getName() {
    return "SequentialTriggerListener";
}

public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
    synchronized (this) {
        if (activeJob != null) {
            getLog().debug("Queueing Sequential Job - " + context.getJobDetail().getKey().getName());
            JobDetail jd = context.getJobDetail();
            activeScheduler = context.getScheduler();
            jd = JobBuilder.newJob().usingJobData(jd.getJobDataMap()).withIdentity(getName() + ":" + jd.getKey().getName(), jd.getKey().getGroup())
                    .ofType(jd.getJobClass()).build();
            queuedJobs.add(jd);
            return true;
        } else {
            activeJob = trigger.getJobKey();
            getLog().debug("Executing Job - " + activeJob.getName());
            return false;
        }
    }
}

public void triggerMisfired(Trigger trigger) {
    triggerFinalized(trigger);
}

public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
    triggerFinalized(trigger);
}

protected void triggerFinalized(Trigger trigger) {
    synchronized (this) {
        try {
            if (trigger.getJobKey().equals(activeJob)) {
                getLog().debug("Finalized Sequential Job - " + activeJob.getName());
                activeJob = null;
                JobDetail jd = queuedJobs.poll();
                if (jd != null) {
                    getLog().debug("Triggering Sequential Job - " + jd.getKey().getName());
                    activeScheduler.scheduleJob(jd,TriggerBuilder.newTrigger().forJob(jd).withIdentity("trigger:" + jd.getKey().getName(), jd.getKey().getGroup())
                            .startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0).withIntervalInMilliseconds(1)).build());
                }
            } else {
                // this should not occur as the trigger finalizing should be the one we are tracking.
                getLog().warn("Sequential Trigger Listener execution order failer");
            }
        } catch (SchedulerException ex) {
            getLog().warn("Sequential Trigger Listener failure", ex);
        }
    }

}

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!