我们有几个设置重试次数为 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}]";
}
}
}
}