Hangfire嵌套批处理错误

时间:2017-06-17 15:50:34

标签: c# 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 个答案:

答案 0 :(得分: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);