2017-06-17 36 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);