簡體   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