Skip to content

Instantly share code, notes, and snippets.

@nickspacek
Created September 28, 2010 13:09
Show Gist options
  • Save nickspacek/600953 to your computer and use it in GitHub Desktop.
Save nickspacek/600953 to your computer and use it in GitHub Desktop.
Abstract Quartz Trigger that will retry itself if requested by concrete implementations
package com.lashpoint.twitter.quartz;
public class RescheduleException extends Error {
/**
*
*/
private static final long serialVersionUID = -253876682421574999L;
public RescheduleException(Throwable t) {
super(t);
}
}
package com.lashpoint.quartz;
import java.util.Calendar;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import com.lashpoint.twitter.quartz.RescheduleException;
public abstract class RetriableTrigger extends SimpleTrigger {
/**
*
*/
private static final long serialVersionUID = 2986291750485640660L;
private static final int DELAY_CEILING = 600; // 15 minutes
private static final int DELAY_EXP_BASE = 2; // Delays will be a power of 2
public RetriableTrigger(String name, Date startDate) {
super(name, startDate, null, 0, 0);
}
@Override
public boolean hasAdditionalProperties() {
return true;
}
@Override
public int executionComplete(JobExecutionContext context,
JobExecutionException result) {
if (shouldReschedule(context, result)) {
try {
RetriableTrigger nextTrigger = createTriggerForReschedule(context,
result);
if (nextTrigger != null) {
context.getScheduler().rescheduleJob(getName(), getGroup(),
nextTrigger);
return INSTRUCTION_NOOP;
}
}
catch (SchedulerException e) {
throw new RescheduleException(e);
}
}
return INSTRUCTION_DELETE_TRIGGER;
}
protected abstract boolean shouldReschedule(JobExecutionContext context,
JobExecutionException result);
protected RetriableTrigger createTriggerForReschedule(JobExecutionContext context,
JobExecutionException result) {
try {
RetriableTrigger trigger = getClass().newInstance();
Calendar nextFireTime = Calendar.getInstance();
nextFireTime.add(Calendar.SECOND, Math.min(DELAY_CEILING,
(int)Math.pow(DELAY_EXP_BASE, getTimesTriggered())));
trigger.setStartTime(nextFireTime.getTime());
trigger.setJobName(getJobName());
trigger.setJobGroup(getJobGroup());
trigger.setTimesTriggered(getTimesTriggered());
return trigger;
}
catch (InstantiationException e) {
throw new RescheduleException(e);
}
catch (IllegalAccessException e) {
throw new RescheduleException(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment