1

我们有几个设置重试次数为 10 的作业。由于自然或外部服务,有时在第一次或第二次过程中会失败,我们会收到失败的电子邮件。但是在第三或第四次工作会成功。现在我想以协调的方式向早期的失败电子邮件发送电子邮件。因此,如果我们收到成功的连续电子邮件,我们可以放心地忽略早期的失败电子邮件。我想按以下模式发送电子邮件标题;所以更容易关联。

Attempt 1 -> Email Header : JobID - JobName - Attempt 1 - Failed
Attempt 2 -> Email Header : JobID - JobName - Attempt 2 - Failed
Attempt 3 -> Email Header : JobID - JobName - Attempt 3 - Succeeded

如何在hangfire中实现这一点?我还想检索给定作业的重试次数。

谢谢

到目前为止我的方法。还有其他更好的方法吗?

namespace Forte.Application.Hangfire.Filter
{
    public class HangFireEmailerFilter : JobFilterAttribute, IElectStateFilter
    {
        private readonly IEmailer _emailer;
        private readonly IHangfireEmailSettings _hangfireSettings;

        public HangFireEmailerFilter(IHangfireEmailSettings hangfireSettings)
        {
            _hangfireSettings = hangfireSettings;
            _emailer = new Emailer(hangfireSettings);
        }

        public void OnStateElection(ElectStateContext context)
        {
            if(context?.CandidateState is FailedState || context?.CandidateState is SucceededState)
            {
                if(_hangfireSettings.IsEnabled)
                { 
                    var emailHeader = string.Empty;
                    var body = string.Empty;
                    int? totalAttemptsAllowed = null;
                    var highPriority = false;
                    var sendEmail = false;

                    var currentRetryCount = context.GetJobParameter<int>("RetryCount");
                    var retryAttribute = (AutomaticRetryAttribute) GetCustomAttribute(context.BackgroundJob.Job.Type, typeof(AutomaticRetryAttribute));

                    var jobId = context.BackgroundJob.Id;

                    if(retryAttribute != null)
                    { 
                        totalAttemptsAllowed = retryAttribute.Attempts;
                    }

                    if (context.CandidateState is FailedState failedState)
                    {
                        //FATAL
                        if(totalAttemptsAllowed.HasValue && currentRetryCount == totalAttemptsAllowed)
                        {
                            emailHeader = $"{EmailLevel.FATAL.ToString()}:{GetEmailSubject(context, currentRetryCount, totalAttemptsAllowed, jobId)}";
                            highPriority = true;
                        }
                        //ERROR
                        else 
                        {
                            emailHeader = $"{EmailLevel.FAIL.ToString()}:{GetEmailSubject(context, currentRetryCount, totalAttemptsAllowed, jobId)}";
                        }
                        body =  _hangfireSettings.JobDashboardUrl + jobId + "\n\n" + failedState.Exception.Message;
                        sendEmail = true;
                    }

                    if (context.CandidateState is SucceededState)
                    {
                        if(currentRetryCount > 1) //OK
                        {
                            emailHeader = $"{EmailLevel.OK.ToString()}:{GetEmailSubject(context, currentRetryCount, totalAttemptsAllowed, jobId)}";
                            body = $"{_hangfireSettings.JobDashboardUrl + jobId} {Environment.NewLine} Job Completed.";
                            sendEmail = true;
                        }
                    }

                    if(sendEmail)
                    { 
                        _emailer.SendEmail(_hangfireSettings.FromEmail, _hangfireSettings.ToEmail, emailHeader, body, highPriority);
                    }
                }
            }
        }

        private string GetEmailSubject(ElectStateContext context, int retryCount, int? totalAttemptsAllowed, string jobId)
        {
            if(totalAttemptsAllowed.HasValue)
            { 
                return $"{context.BackgroundJob.Job.Type.Name}.{context.BackgroundJob.Job.Method.Name} " +
                       $"[{jobId}:{retryCount}/{totalAttemptsAllowed.Value}][{_hangfireSettings.ProcessName}][{_hangfireSettings.MachineName}]";
            }
            else
            {
                return $"{context.BackgroundJob.Job.Type.Name}.{context.BackgroundJob.Job.Method.Name} " +
                       $"[{jobId}:{retryCount}][{_hangfireSettings.ProcessName}][{_hangfireSettings.MachineName}]";
            }
        }
    }
}
4

0 回答 0