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

tra*_*max 9 c# hangfire

我通过ContinueJobWith<MyHandler>(parentJobId, x => x.DoWork()).

但是,第二个作业没有得到处理并且始终处于Awaiting状态: 父母成功,但工作未处理

工作本身是这样的: 卡在排队

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

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

这没有任何区别。

这是作业的执行方式:

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()));
Run Code Online (Sandbox Code Playgroud)

所有参数都是int,boolstring。如果我手动将等待的作业排入队列,它们将毫无问题地执行。

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

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

Jaw*_*wad 7

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

根据关于 ContinueJobWith 的 Hangfire 文档,“在其父作业完成后执行继续”。从您的屏幕截图中,尚不清楚 JobID: 发生了什么216347。一旦这项工作216347完成,带有 ID 的工作就216349应该开始了。如果您希望216349216348完成后开始,请检查您的代码并确保将正确的 ParentID 传递给第二个作业。


更新

基于这个线程,添加ContinuationsSupportAttributeGlobalJobFilters.Filter你配置 Hangfire 服务的地方。这应该让您的 Hangfire 实例知道继续作业。

GlobalJobFilters.Filters.Add(new ContinuationsSupportAttribute());
Run Code Online (Sandbox Code Playgroud)


tra*_*max 1

经过调查,结果发现我们正在用JobFilterProviderCollection我们自己的收藏来替换:

    var filterProviderCollection = new JobFilterProviderCollection
    {
        new MyFilterProvider(...)
    };
    var backgroundJobClient = new BackgroundJobClient(JobStorage.Current, filterProviderCollection);
Run Code Online (Sandbox Code Playgroud)

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),
        };
    }
Run Code Online (Sandbox Code Playgroud)

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

    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;
    }
Run Code Online (Sandbox Code Playgroud)