我正在处理一个Web API RESTful服务,该服务在请求中需要执行任务。我们使用Hangfire将该任务作为一项工作执行,如果失败,将尝试重试该作业最多10次。
如果作业最终成功,我想运行一个额外的工作(将事件发送到另一个服务)。如果即使在所有重试尝试之后作业仍然失败,我想运行另一个额外的作业(将失败事件发送到另一个服务)。
然而,我无法弄清楚如何做到这一点。我创建了以下JobFilterAttribute:
public class HandleEventsAttribute : JobFilterAttribute, IElectStateFilter
{
public IBackgroundJobClient BackgroundJobClient { get; set; }
public void OnStateElection(ElectStateContext context)
{
var failedState = context.CandidateState as FailedState;
if (failedState != null)
{
BackgroundJobClient.Enqueue<MyJobClass>(x => x.RunJob());
}
}
}
我遇到的一个问题是将IBackgroundJobClient注入此属性。我不能将它作为属性传递给属性(我得到一个“无法在静态上下文中访问非静态字段'backgroundJobClient'”错误)。我们使用autofac进行依赖注入,我试图弄清楚如何使用属性注入,但我很茫然。所有这些让我相信我可能走错了路。
如果Hangfire作业失败,我认为运行一些额外的清理代码是一种相当常见的模式。大多数人如何做到这一点?
感谢您的帮助。如果我能提供任何其他详细信息,请告诉我。
答案 0 :(得分:1)
Hangfire可以构建执行链。如果您想在第一个作业成功后安排下一个作业,则需要ContinueWith(string parentId, Expression<Action> methodCall, JobContinuationOptions options);
使用JobContinuationOptions.OnlyOnSucceededState
才能在成功后运行它。
但您可以像JobExecutor一样创建一个HangFire扩展,并在其中运行任务以获得更多可能性。
类似的东西:
public static JobResult<T> Enqueue<T>(Expression<Action> a, string name)
{
var exprInfo = GetExpressionInfo(a);
Guid jGuid = Guid.NewGuid();
var jobId = BackgroundJob.Enqueue(() => JobExecutor.Execute(jGuid, exprInfo.Method.DeclaringType.AssemblyQualifiedName, exprInfo.Method.Name, exprInfo.Parameters, exprInfo.ParameterTypes));
JobResult<T> result = new JobResult<T>(jobId, name, jGuid, 0, default(T));
JobRepository.WriteJobState(new JobResult<T>(jobId, name, jGuid, 0, default(T)));
return result;
}
您可以在此处找到更详细的信息:https://indexoutofrange.com/Don%27t-do-it-now!-Part-5.-Hangfire-job-continuation,-ContinueWith/
答案 1 :(得分:0)
我还没有能够验证这是否有效,但是BackgroundJobClient没有静态方法,所以你需要引用它的实例。
当我将任务排入队列时,我使用静态Hangfire.BackgroundJob.Enqueue,它应该在不引用JobClient实例的情况下工作。
史蒂夫