2017-06-17 91 views
1

我們已經在我們的幾個系統上成功使用了Hangfire一段時間,併成功地使用了Hangfire批處理功能並行執行任務,但是我們遇到了一些問題,試圖使用它在一個連續的工作上。Hangfire嵌套批處理出錯

使用一個簡單的批處理細如下工作:

BatchJob.Attach(masterBatch, batch => 
    { 
     var lockJobId = batch.Enqueue<IProcessJob>(job => job.ObtainLock(businessUnit)); 

     var preparationJobId = batch.ContinueWith<IPrepareProcessJob>(lockJobId, 
      job => job.PrepareData(businessUnit, workingJobData, JobCancellationToken.Null)); 

     var statisticsJobId = batch.ContinueWith<IPrepareProcessJob>(preparationJobId, 
      job => job.AddStatistics(businessUnit, workingJobData, JobCancellationToken.Null)); 

     var processFileId = batch.ContinueWith<IProcessJob>(statisticsJobId, 
      job => job.ProcessFile(workingJobData, notifierInstructions, businessUnit, 
          JobCancellationToken.Null)); 

     batch.ContinueWith<IProcessJob>(processFileId, job => job.ReleaseLock(businessUnit)); 
    }); 

但是我們要始終運行最終解鎖工作的三個處理作業無論發生什麼事情,因此我們嘗試引入中間的三個工作圍繞嵌套批如下:

BatchJob.Attach(masterBatch, batch => 
    { 
     var lockJobId = batch.Enqueue<IProcessJob>(job => job.ObtainLock(businessUnit)); 

     var mainBatchId = batch.AwaitJob(lockJobId, mainBatch => 
     { 
      var preparationJobId = mainBatch.Enqueue<IPrepareProcessJob>(
       job => job.PrepareData(businessUnit, jobData, JobCancellationToken.Null)); 

      var statisticsJobId = mainBatch.ContinueWith<IPrepareProcessJob>(preparationJobId, 
       job => job.AddStatistics(businessUnit, jobData, JobCancellationToken.Null)); 

      mainBatch.ContinueWith<IProcessJob>(statisticsJobId, 
       job => job.ProcessFile(jobData, notifierInstructions, businessUnit, 
        JobCancellationToken.Null)); 
     }); 

     batch.AwaitBatch<IProcessJob>(mainBatchId, job => job.ReleaseLock(businessUnit)); 
    }); 

這將產生錯誤:

Can't create a continuation for batch 'a5955434-294e-4568-9b64-c167feeb95da' because it doesn't exist. 

當Hangfire嘗試附加最終的釋放鎖時,正在調查錯誤。有沒有人對我們可能做錯了什麼提出任何建議?

回答

1

我們花了好幾個小時試圖解決這個問題,我們仍然無法獲得嵌套批處理的版本而不會拋出錯誤,但是通過一些重新佈置,我們可以在不嵌套的情況下獲得所需的功能:

BatchJob.Attach(mainBatchId, batch => 
{ 
    var lockJobId = batch.Enqueue<IProcessJob>(job => job.ObtainLock(businessUnit)); 

    var preparationJobId = batch.ContinueWith<IPrepareProcessJob>(lockJobId, 
     job => job.PrepareData(businessUnit, workingJobData, JobCancellationToken.Null)); 

    var statisticsJobId = batch.ContinueWith<IPrepareProcessJob>(preparationJobId, 
     job => job.AddStatistics(businessUnit, workingJobData, JobCancellationToken.Null)); 

    batch.ContinueWith<IProcessJob>(statisticsJobId, 
     job => job.ProcessFile(workingJobData, notifierInstructions, businessUnit, 
      JobCancellationToken.Null)); 
}); 

// Catch-all unlock 
BatchJob.AwaitBatch(mainBatchId, 
    batch => batch.Enqueue<IProcessJob>(job => job.ReleaseLock(businessUnit)), 
    $"Unlock for {reportName}", BatchContinuationOptions.OnAnyFinishedState);