Ошибка с вложенными пакетами 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 пытается прикрепить последний Release Lock. Есть ли у кого-нибудь предложения относительно того, что мы делаем не так?


person RTPeat    schedule 17.06.2017    source источник


Ответы (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); 
person RTPeat    schedule 19.06.2017