【问题标题】:Hangfire - Configure AutomaticRetry for specific RecurringJob at runtimeHangfire - 在运行时为特定的 RecurringJob 配置 AutomaticRetry
【发布时间】:2020-03-13 11:02:17
【问题描述】:

我正在使用 Hangfire v1.7.9,并尝试在我的 MVC 5 应用程序中配置一系列重复的后台作业,以自动将外部参考数据检索到应用程序中。我已经用一项任务对此进行了测试,效果很好,但我希望系统内的管理员能够配置与在这些后台作业中调用的方法相关联的 AttemptsDelayInSeconds 属性参数。

AutomaticRetryAttribute 声明您必须使用...

...属性参数类型的常量表达式、typeof表达式或数组创建表达式

...从我所读到的内容中,这是所有属性的典型特征。但是,这意味着我无法通过在其他地方设置属性值然后在包含我要运行的方法的类中引用它来实现我的目标。

此外,似乎没有任何方法可以在 BackgroundJob.EnqueueRecurringJob.AddOrUpdate 方法中配置自动重试属性。最后,我查看了您是否可以为每个命名队列使用特定的重试计数,但遗憾的是,您可以设置的关于 Hangfire 队列的唯一属性是它们在 Hangfire 服务器初始化时在 BackgroundJobServerOptions 类中的名称。

我是否已经用尽了这里的所有途径?我能想到的唯一另一件事是使用 int 枚举来create my own implementation of the AutomaticRetryAttribute and set the values at compile time,尽管这本身会产生一个问题,因为我需要提供用户需要的每个值的定义列表选择。因为我希望重试次数可以从 5 分钟一直到 1440 分钟(24 小时)进行配置,所以我真的不希望每个可用值都有一个庞大而笨重的 enum : int。有没有人遇到过这个问题,或者这是我应该在 Hangfire GitHub 上作为请求提交的东西吗?

【问题讨论】:

    标签: c# asp.net-mvc hangfire


    【解决方案1】:

    我会采用自定义属性来装饰AutomaticRetryAttribute

    public class MyCustomRetryAttribute : JobFilterAttribute, IElectStateFilter, IApplyStateFilter
    {
        public void OnStateElection(ElectStateContext context)
        {
            GetAutomaticRetryAttribute().OnStateElection(context);
        }
    
        public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
            GetAutomaticRetryAttribute().OnStateApplied(context, transaction);
        }
    
        public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
            GetAutomaticRetryAttribute().OnStateUnapplied(context, transaction);
        }
    
        private AutomaticRetryAttribute GetAutomaticRetryAttribute()
        {
            // Somehow instantiate AutomaticRetryAttribute with dynamically fetched/set `Attempts` value
            return new AutomaticRetryAttribute { Attempts = /**/ };
        }
    }
    

    编辑:澄清一下,此方法允许您重用AutomaticRetryAttribute 的逻辑,而无需复制它。但是,如果您需要在每个作业的基础上更改更多方面,您可能需要在自己的属性中复制逻辑。

    另外,您可以使用context.GetJobParameter<T> 来存储每个作业的任意数据

    【讨论】:

    • 嗨@Xymanek,这很有用...我认为通过使用context.GetJobParameter<T> 方法,我可以从作业中检索配置模型对象,然后从那里实现重试次数:)跨度>
    • AutomaticRetryAttribute 实际上使用 context.GetJobParameter<T> 工作,所以你可以从那里获得灵感
    • 我尝试了自定义属性方法,但是一旦重试次数用尽,它似乎会回退到默认设置,即重试 10 次而不是我的自定义 3 次。起初它会报告“trying 2 of 3”,然后改为“trying 4 of 10”!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 2021-09-26
    相关资源
    最近更新 更多