I have searched for an answer on how to retrigger a job after a ceratin amount of time, if the job throws an exception. I cannot see any simple way of doing this.
if I set my trigger up like this:
JobDetail job = new JobDetail("Download catalog", null, typeof(MyJob));
job .Durable = true;
Trigger trigger= TriggerUtils.MakeDailyTrigger(12, 0);
trigger.StartTimeUtc = DateTime.UtcNow;
trigger.Name = "trigger name";
scheduler.ScheduleJob(job , trigger);
And MyJob look like this:
public class MyJob : IJob
{
public void Execute(JobExecutionContext context)
{
var service = new service();
try
{
service.Download();
}
catch (Exception)
{
throw;
}
}
}
how do I make the trigger to refire/retrigger after there is gone 15 minutes if the service.Download() call throws some sort of Exception?
I think the only option you have is to trap the error and tell Quartz.net to refire immediately:
public class MyJob : IJob
{
public void Execute(JobExecutionContext context)
{
var service = new service();
try
{
service.Download();
}
catch (Exception ex)
{
JobExecutionException qe = new JobExecutionException(ex);
qe.RefireImmediately = true; // this job will refire immediately
throw qe;
}
}
}
You can find some info here and here.
UPDATE:
I did some tests and it seems that you can schedule a new trigger inside an executing job.
You can try something like this:
public class MyJob : IJob
{
public void Execute(JobExecutionContext context)
{
var service = new service();
try
{
service.Download();
}
catch (Exception ex)
{
JobExecutionException qe = new JobExecutionException(ex);
// qe.RefireImmediately = true; // this job will refire immediately
// throw qe;
OnErrorScheduleJob(context);
}
}
private void OnErrorScheduleJob(JobExecutionContext context)
{
var jobOnError = context.Scheduler.GetJobDetail("ONERRORJOB", "ERROR");
if (jobOnError == null)
{
JobDetail job = new JobDetail("ONERRORJOB", "ERROR", typeof(MyJob));
job.Durable = false;
job.Volatile = false;
job.RequestsRecovery = false;
SimpleTrigger trigger = new SimpleTrigger("ONERRORTRIGGER",
"ERROR",
DateTime.UtcNow.AddMinutes(15),
null,
1,
TimeSpan.FromMinutes(100));
context.Scheduler.ScheduleJob(job, trigger);
}
}
}
Actually, its not necessary to create a new JobDetail like described by LeftyX. You can just schedule a new trigger that is connected to the JobDetail from the current context.
public void Execute(JobExecutionContext context) {
try {
// code
} catch (Exception ex) {
SimpleTriggerImpl retryTrigger = new SimpleTriggerImpl(Guid.NewGuid().ToString());
retryTrigger.Description = "RetryTrigger";
retryTrigger.RepeatCount = 0;
retryTrigger.JobKey = context.JobDetail.Key; // connect trigger with current job
retryTrigger.StartTimeUtc = DateBuilder.NextGivenSecondDate(DateTime.Now, 30); // Execute after 30 seconds from now
context.Scheduler.ScheduleJob(retryTrigger); // schedule the trigger
JobExecutionException jex = new JobExecutionException(ex, false);
throw jex;
}
}
This is less error prone than creating a new JobDetail. Hope that helps.
I think that the right answer is to use JobListener to retry a job as described here: http://thecodesaysitall.blogspot.cz/2012/03/quartz-candy-part-1.html.
You separate retry logic from Job itself in this solution, so it can be reused.
If you implement retry logic in job as suggested in another replies here, it must be implemented again in every job.
Edit: According to the Ramanpreet Singh note better solution can be found here: https://blog.harveydelaney.com/quartz-job-exception-retrying/
// don't forget to use @PersistJobDataAfterExecution without it, the jobExecutionContext will reset the value of count.
SimpleTriggerImpl retryTrigger = new SimpleTriggerImpl();
retryTrigger.setName("jobname");
retryTrigger.setRepeatCount(0);
retryTrigger.setJobKey(jobExecutionContext.getJobDetail().getKey());
final Calendar cal = getCalendarInstance();
cal.add(Calendar.MINUTE, 1); //retry after one minute
retryTrigger.setStartTime(cal.getTime());
try {
jobExecutionContext.getScheduler().scheduleJob(retryTrigger); // schedule the trigger
} catch (SchedulerException ex) {
logger.error("something went wrong", ex);
}
JobExecutionException e2 = new JobExecutionException("retrying...");
e2.refireImmediately();
throw e2;
来源:https://stackoverflow.com/questions/10893559/refire-quartz-net-trigger-after-15-minutes-if-job-fails-with-exception