我有一些作业是通过ContinueJobWith<MyHandler>(parentJobId, x => x.DoWork())
一个接一个地执行的。
但是,第二项作业没有得到处理,始终处于Awaiting
状态:
为什么会发生这种情况以及在哪里检查结果?
JobActivator
实现,因为我们必须处理多租户。 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()));
所有参数均为int
,bool
或string
。如果我手动排队等待的作业,它们将被执行而没有任何问题。
我添加了Hangfire日志记录,但是在那里看不到任何问题:服务器启动,停止,作业更改状态,但是在那里看不到任何明显的错误。
我还应该考虑哪些其他事项,或者在哪里/应该如何调试?
答案 0 :(得分:6)
从外观上看,ID为216348
的第一个作业已成功完成,但是ID为216349
的第二个作业正在等待父ID 216347
。根据Hangfire的文档和经验,parentID应该是您在执行第二个作业之前等待完成的作业。
根据Hangfire documentation on ContinueJobWith,“ 其父作业已完成 时执行继续。”从您的屏幕截图中,并不清楚JobID:216347
的情况。 216347
作业完成后,ID为216349
的作业应开始。如果您期望216349
在216348
完成之后开始,请检查代码并确保将正确的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;
}