尽管父级作业已成功完成,但Hangfire ContinueWithJob仍处于等待状态

时间:2020-06-30 23:01:42

标签: c# hangfire

我有一些作业是通过ContinueJobWith<MyHandler>(parentJobId, x => x.DoWork())一个接一个地执行的。

但是,第二项作业没有得到处理,始终处于Awaiting状态: Parent is Succeeded, but job is not procssesed

工作本身是这样的: Stuck in Enqueued

为什么会发生这种情况以及在哪里检查结果?

  • 我们将Autofac用作DI容器,但是我们有自己的JobActivator实现,因为我们必须处理多租户。
  • 我们正在使用SQL Server 2019进行存储。
  • Hangfire版本为1.7.10
  • 这是MVC 5应用程序
  • 我在任何日志中或调试期间都没有看到任何错误/异常
  • 完成this之后,我已将其添加到我们的Autofac注册中
            builder.RegisterType<BackgroundJobStateChanger>()
                   .As<IBackgroundJobStateChanger>()
                   .InstancePerLifetimeScope();

这没什么区别。

这是作业的执行方式:

var parentJobId = _backgroundJobClient.Schedule<Handler>(h => h.ConvertCertToTraining(certId, command.SetUpOneToOneRelationship), TimeSpan.FromSeconds(1));
var filesCopyJObId = _backgroundJobClient.ContinueJobWith<Handler>(parentJobId, h => h.CopyAttachedFiles());
_backgroundJobClient.ContinueJobWith<Handler>(filesCopyJObId, h => h.NotifyUser(command.CertificationToBeConvertedIds, _principal.GetEmail()));

所有参数均为intboolstring。如果我手动排队等待的作业,它们将被执行而没有任何问题。

我添加了Hangfire日志记录,但是在那里看不到任何问题:服务器启动,停止,作业更改状态,但是在那里看不到任何明显的错误。

我还应该考虑哪些其他事项,或者在哪里/应该如何调试?

2 个答案:

答案 0 :(得分:6)

从外观上看,ID为216348的第一个作业已成功完成,但是ID为216349的第二个作业正在等待父ID 216347。根据Hangfire的文档和经验,parentID应该是您在执行第二个作业之前等待完成的作业。

根据Hangfire documentation on ContinueJobWith,“ 其父作业已完成 时执行继续。”从您的屏幕截图中,并不清楚JobID:216347的情况。 216347作业完成后,ID为216349的作业应开始。如果您期望216349216348完成之后开始,请检查代码并确保将正确的ParentID传递给第二个作业。


更新

基于on this thread,将ContinuationsSupportAttribute添加到GlobalJobFilters.Filter,在其中配置Hangfire服务。这应该使您的Hangfire实例知道继续作业。

GlobalJobFilters.Filters.Add(new ContinuationsSupportAttribute());

答案 1 :(得分:1)

在调查期间,事实证明我们正在用自己的收藏集替换JobFilterProviderCollection

    var filterProviderCollection = new JobFilterProviderCollection
    {
        new MyFilterProvider(...)
    };
    var backgroundJobClient = new BackgroundJobClient(JobStorage.Current, filterProviderCollection);

MyFilterProvider看起来像这样:

    public IEnumerable<JobFilter> GetFilters(Job job)
    {
        return new JobFilter[]
        {
             new JobFilter(new HangfireTenantFilter(_tenantDetail, _principal), JobFilterScope.Global,  null),
             new JobFilter(new HangfireFunctionalityFilter(_functionalityFilter), JobFilterScope.Global, null),
        };
    }

事实证明,在Continuation上进行工作的代码仅从此过滤器集合中获取了过滤器,而ContinuationsSupportAttribute在正确的时间没有在那里执行。因此,从GlobalJobFilters.Filters重新添加默认的Hangfire过滤器可以解决这种情况:

    public IEnumerable<JobFilter> GetFilters(Job job)
    {
        var customFilters = new List<JobFilter>()
        {
             new JobFilter(new HangfireTenantFilter(_tenantDetail, _principal), JobFilterScope.Global,  null),
             new JobFilter(new HangfireFunctionalityFilter(_functionalityFilter), JobFilterScope.Global, null),
        };
        customFilters.AddRange(GlobalJobFilters.Filters);

        return customFilters;
    }
相关问题