繁体   English   中英

当一段时间没有运行另一个作业时,如何配置Quartz.net来运行一个作业

[英]How does one configure Quartz.net to run a job when another job hasn't run for a period

假设我有两个Quartz.net作业

  • 下载一段时间内(例如24h)具有变化增量的CSV文件,然后导入数据(称为IncrementalImportJob
  • 下载包含所有记录的CSV文件,然后导入数据(称为FullImportJob

要求是在该时间段内(例如24h)至少要执行一次IncrementalImportJob 如果错过了该窗口,或者作业未成功完成,则应改为运行FullImportJob 原因是当天(缺失)的更改不会被导入。 这种情况非常特殊。

FullImportJob需要资源(时间,CPU,数据库,内存)来导入所有数据,这可能会影响其他系统。 此外,变化的增量通常很小或根本不存在。 因此,目标是尽可能支持运行IncrementalImportJob

如果IncrementalImportJob在特定时间段内(例如24小时)未成功完成,如何配置quartz.net以运行FullImportJob

在网络上搜索“ quartz.net恢复”和“ quartz.net失火”并不能显示其是否受支持甚至是否可能。

quartz.net中有本机的失火处理,但是它只能说明是否应立即重新启动该作业,还是应在失火后一段时间或多次启动。

我认为一种选择是从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 
}

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM