假设我有两个Quartz.net作业
IncrementalImportJob
)FullImportJob
)要求是IncrementalImportJob
至少一段时间(例如24小时)。如果错过了该窗口,或者作业未成功完成,则应运行FullImportJob
。原因是不会导入该(错过)日的更改。这种情况非常特殊。
FullImportJob需要资源(时间,CPU,数据库,内存)来导入所有数据,这可能会影响其他系统。此外,变化的增量通常很小或不存在。因此,我们的目标是尽可能支持运行IncrementalImportJob
。
如果FullImportJob
在特定时间段(例如24小时)内未成功完成,那么如何配置quartz.net来运行IncrementalImportJob
?
在网上搜索“quartz.net recovery”和“quartz.net misfire”并未显示其是否受支持或是否可能。
答案 0 :(得分:0)
在quartz.net中存在本机失火处理,但它只能指定作业是否应该触发immediately again, or after a period of time or a number of times after misfiring.
我认为一个选项是从IncrementalImportJob内部处理它。
try
{
//download data
//import data
}
catch (Exception e) //something went wrong
{
//log the error
UpdateFullImportJobTrigger(sched);
}
//Reschedule FullImportJob to run at a time of your choosing.
public void UpdateFullImportJobTrigger(IScheduler sched)
{
Trigger oldTrigger = sched.getTrigger(triggerKey("oldTrigger", "group1");
TriggerBuilder tb = oldTrigger.getTriggerBuilder();
//if you want it to run based on a schedule use this:
Trigger newTrigger = tb.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(10)
.build();
sched.rescheduleJob(oldTrigger.getKey(), newTrigger);
//or use simple trigger if you want it to run immediately and only once so that
//it runs again on schedule the next time.
}
这是一种做法。另一种方法是将此逻辑抽象为每隔一段时间检查日志的维护作业,如果它从IncrementalImportJob中发现失败消息,则会触发FullImportJob。但是,这在某种程度上取决于您的日志记录系统(大多数人使用NLog或log4net)。
另一方面,如果您担心的是该作业从未在第一时间运行,例如,应用程序/数据库/服务器已关闭,您可以安排FullImportJob在几小时后启动并检查IncrementalImportJob是否有解雇如下:
//this is done from FullImportJob
//how you retrieve triggerKey will depend on whether
//you are using RAMJobStore or ADO.NET JobStore
public void Execute(IJobExecutionContext context)
{
ITrigger incImportJobTrigger = context.Scheduler.GetTrigger(triggerKey);
//if the job has been rescheduled with a new time quartz will set this to null
if (!incImportJobTrigger.GetPreviousFireTimeUtc().HasValue) return;
DateTimeOffset utcTime = incImportJobTrigger.GetPreviousFireTimeUtc().Value;
DateTime previousTireTime = utcTime.LocalDateTime;
if (previousTireTime.Day == DateTime.Now.Day) return;
//IncrementalImportJob has not ran today, let's run FullImportJob
}
希望这有帮助。