All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.turbospaces.quartz.JobsDispatcher Maven / Gradle / Ivy
package com.turbospaces.quartz;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
import org.apache.commons.lang3.time.StopWatch;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobPersistenceException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.quartz.listeners.TriggerListenerSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Suppliers;
import com.google.common.util.concurrent.MoreExecutors;
import com.netflix.archaius.api.Property;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public interface JobsDispatcher {
default StopWatch runOnce(Scheduler scheduler, JobBuilder job, TriggerKey triggerKey) {
Mono flux = runOnceAsync(scheduler, job, triggerKey, MoreExecutors.directExecutor());
return flux.block();
}
default Mono runOnceAsync(Scheduler scheduler, JobBuilder job, TriggerKey triggerKey, Executor exectutor) {
JobDetail jobDetail = job.storeDurably().build();
return Mono.fromCallable(new Callable() {
@Override
public StopWatch call() throws Exception {
StopWatch stopWatch = StopWatch.createStarted();
String k = "run-once-uuid";
String v = UUID.randomUUID().toString();
TriggerBuilder now = TriggerBuilder.newTrigger();
now.withIdentity(triggerKey);
now.startAt(new Date()); // ~ as of now
now.forJob(jobDetail);
now.usingJobData(k, v);
try {
CountDownLatch latch = new CountDownLatch(1);
TriggerListenerSupport listener = new TriggerListenerSupport() {
@Override
public String getName() {
return now.toString();
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
if (context.getJobDetail().equals(jobDetail)) {
if (v.equals(context.getTrigger().getJobDataMap().get(k))) {
latch.countDown();
}
}
}
};
scheduler.getListenerManager().addTriggerListener(listener); // ~ add listener
scheduler.addJob(jobDetail, true);
scheduler.scheduleJob(now.build());
latch.await(); // ~ await for completion
scheduler.getListenerManager().removeTriggerListener(listener.getName()); // ~ remove listener
return stopWatch;
} catch (Exception err) {
throw new RuntimeException(err);
}
}
}).subscribeOn(Schedulers.fromExecutor(exectutor));
}
default void scheduleEnabledJob(Scheduler instance, JobBuilder job, Trigger trigger, Supplier runOnStart) throws SchedulerException {
scheduleJob(instance, job, trigger, Suppliers.ofInstance(true), runOnStart);
}
default void scheduleJob(
Scheduler instance,
JobBuilder job,
Trigger trigger,
Supplier enabled,
Supplier runOnStart) throws SchedulerException {
JobDetail jobDetail = job.storeDurably().build();
//
// if there is not such class anymore
//
try {
instance.getJobDetail(jobDetail.getKey());
} catch (JobPersistenceException err) {
if (err.getCause() instanceof ClassNotFoundException) {
instance.deleteJob(jobDetail.getKey());
}
}
if (enabled.get()) {
if (runOnStart.get()) {
if (instance.checkExists(jobDetail.getKey())) {
instance.triggerJob(jobDetail.getKey());
}
}
}
// replace trigger if needed
Logger logger = LoggerFactory.getLogger(getClass());
if (instance.checkExists(jobDetail.getKey())) {
if (enabled.get()) {
boolean reschedule = false;
Trigger prev = instance.getTrigger(trigger.getKey());
if (prev != null) {
if (prev.getClass().equals(trigger.getClass())) {
if (trigger instanceof SimpleTriggerImpl) {
SimpleTriggerImpl newTrigger = (SimpleTriggerImpl) trigger;
SimpleTriggerImpl prevTrigger = (SimpleTriggerImpl) prev;
if (newTrigger.getRepeatInterval() == prevTrigger.getRepeatInterval()) {
logger.debug("simple trigger = {} has not changed since last run ...", trigger.getKey());
} else {
reschedule = true;
}
} else if (trigger instanceof CronTriggerImpl) {
CronTriggerImpl newTrigger = (CronTriggerImpl) trigger;
CronTriggerImpl prevTrigger = (CronTriggerImpl) prev;
if (newTrigger.getCronExpression().equals(prevTrigger.getCronExpression())) {
logger.debug("cron trigger = {} has not changed since last run ...", trigger.getKey());
} else {
reschedule = true;
}
}
}
}
instance.resumeJob(jobDetail.getKey());
if (reschedule) {
logger.info("detected changes in trigger, re-scheduling job={} to use new trigger={} now ...", jobDetail.getKey(), trigger);
instance.rescheduleJob(trigger.getKey(), trigger);
} else {
TriggerState state = instance.getTriggerState(trigger.getKey());
logger.debug("trigger {} is currently is in state: {}", trigger.getKey(), state.name().toLowerCase());
}
} else {
logger.info("pausing existing job = {}", jobDetail.getKey());
instance.pauseJob(jobDetail.getKey());
}
} else {
if (enabled.get()) {
logger.info("scheduling new job = {} now", jobDetail.getKey());
instance.scheduleJob(jobDetail, trigger);
}
}
}
default Trigger secondlyTriggerWithMisfireNowWithExistingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatSecondlyForever(frequency.get()).withMisfireHandlingInstructionNowWithExistingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger secondlyTriggerWithMisfireNowWithRemainingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatSecondlyForever(frequency.get()).withMisfireHandlingInstructionNowWithRemainingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger secondlyTriggerWithMisfireNextWithExistingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatSecondlyForever(frequency.get()).withMisfireHandlingInstructionNextWithExistingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger secondlyTriggerWithMisfireNextWithRemainingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatSecondlyForever(frequency.get()).withMisfireHandlingInstructionNextWithRemainingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger minutelyTriggerWithMisfireNowWithExistingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatMinutelyForever(frequency.get()).withMisfireHandlingInstructionNowWithExistingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger minutelyTriggerWithMisfireNowWithRemainingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatMinutelyForever(frequency.get()).withMisfireHandlingInstructionNowWithRemainingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger minutelyTriggerWithMisfireNextWithExistingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatMinutelyForever(frequency.get()).withMisfireHandlingInstructionNextWithExistingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger minutelyTriggerWithMisfireNextWithRemainingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatMinutelyForever(frequency.get()).withMisfireHandlingInstructionNextWithRemainingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger hourlyWithMisfireNowWithExistingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatHourlyForever(frequency.get()).withMisfireHandlingInstructionNowWithExistingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger hourlyTriggerWithMisfireNowWithRemainingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatHourlyForever(frequency.get()).withMisfireHandlingInstructionNowWithRemainingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger hourlyTriggerWithMisfireNextWithExistingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatHourlyForever(frequency.get()).withMisfireHandlingInstructionNextWithExistingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
default Trigger hourlyTriggerWithMisfireNextWithRemainingCount(TriggerKey triggerKey, Property frequency) {
SimpleScheduleBuilder schedule = SimpleScheduleBuilder.repeatHourlyForever(frequency.get()).withMisfireHandlingInstructionNextWithRemainingCount();
return TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(schedule).build();
}
}