Quartz RescheduleJob正在为我创造新的工作,而不是像预期的那样

时间:2018-06-21 15:48:16

标签: quartz-scheduler quartz.net quartz

我遇到了Quartz和RescheduleJob函数的问题。 我有一个电子邮件处理器队列,并且正在为未处理的电子邮件进行重新计划。电子邮件具有重试计数(每一个),如果电子邮件发送过程失败,则重试计数会增加,并且电子邮件已入队。每次处理器启动时,都会处理队列中的电子邮件。 问题事实是,在应用启动时,新的计划作业会在最短的时间(1分钟)内出现在具有不同实例的情况下,并且看起来并不相同。

在文档中说:

  

使用给定的密钥删除(删除)Quartz.ITrigger,并存储   新赠与-必须与同一工作相关联(新   触发器必须指定作业名称和组)-但是,新   触发器不必与旧触发器具有相同的名称。

但是在我的日志中却是:

2018-06-21 10:03:21,201 [DefaultQuartzScheduler_Worker-1] INFO  Services.BaseService [(null)] - Email Send error. Contact Form | To:esddaada@test.com Subject: Thank You for Contacting. Email moved to Send Queue.
2018-06-21 10:04:05,177 [DefaultQuartzScheduler_Worker-1] WARN  Services.EmailJob [(null)] - EmailJob Time elapsed updated to 2 mins.
2018-06-21 10:04:07,874 [DefaultQuartzScheduler_Worker-2] INFO  Services.BaseService [(null)] - Email Send error. Contact Form | To:esddaada@test.com Subject: Thank You for Contacting Us. Email moved to Send Queue.
2018-06-21 10:04:59,900 [DefaultQuartzScheduler_Worker-2] WARN  Services.EmailJob [(null)] - EmailJob Time elapsed updated to 4 mins.
2018-06-21 10:05:03,595 [DefaultQuartzScheduler_Worker-3] INFO  Services.BaseService [(null)] - Email Send error. Contact Form | To:esddaada@test.com Subject: Thank You for Contacting Us. Email moved to Send Queue.
2018-06-21 10:05:08,439 [DefaultQuartzScheduler_Worker-3] WARN  Services.EmailJob [(null)] - EmailJob Time elapsed updated to 6 mins.
2018-06-21 10:05:11,155 [DefaultQuartzScheduler_Worker-4] INFO  Services.BaseService [(null)] - Email Send error. Contact Form | To:esddaada@test.com Subject: Thank You for Contacting Us. Email moved to Send Queue.
2018-06-21 10:05:18,871 [DefaultQuartzScheduler_Worker-4] WARN  Services.EmailJob [(null)] - EmailJob Time elapsed updated to 8 mins.
2018-06-21 10:05:22,539 [DefaultQuartzScheduler_Worker-5] INFO  Services.BaseService [(null)] - Email Send error. Contact Form | To:esddaada@test.com Subject: Thank You for Contacting Us. Email moved to Send Queue.
2018-06-21 10:05:22,551 [DefaultQuartzScheduler_Worker-5] ERROR Services.EmailJob [(null)] - Email on Queue Reach max 6 send retry Times! Application: To:esddaada@test.com Subject:Thank You for Contacting Us. 

这是我的代码:

public static void StartEmailJob() // scheduler called on Application_Start()
    {

        var scheduler = StdSchedulerFactory.GetDefaultScheduler();

        var emailJob = JobBuilder.Create<EmailJob>().Build();

        var trigger = TriggerBuilder.Create()
            .WithIdentity("EmailJob", "group1")
           // .StartAt(DateTimeOffset.Now.AddMinutes(1))
            .WithSimpleSchedule(sh => sh
                .WithIntervalInMinutes(RetryInterval)
                .RepeatForever())
            .Build();
        scheduler.ScheduleJob(emailJob, trigger);

        scheduler.Start();

    }


[DisallowConcurrentExecution]
    public class EmailJob : IJob
    {
      public void Execute(IJobExecutionContext context)
       {
            var retryCount = 5;

         var emailsQueue = context.Emails;
            if (emailsQueue.Any(ml => ml.RetryCount < retryCount))
            {
                var emails = emailsQueue .Where(ml => ml.RetryCount < retryCount);

                var count = emails.FirstOrDefault().RetryCount;

                foreach (var email in emails)
                {
                    if (!EmailService.SendEmail(email, out string error))
                    {

                        if (email.RetryCount >= retryCount)
                        {
                            Logger.Error($"Email on Queue Reach max {retryCount} send retry Times!");
                        }
                    }
                    else
                    {
                       //remove email from queue
                    }
                }


                try
                {
                    RescheduleJob(context, count, true);
                }
                catch (Exception exc)
                {
                    Logger.Error("EmailJob RescheduleJob Error!", exc);
                }
            }
            else
            {
                try
                {
                    RescheduleJob(context, 0, true);
                }
                catch (Exception exc)
                {
                    Logger.Error("EmailJob RescheduleJob Error!", exc);
                }
            }
        }
    }

    public void RescheduleJob(IJobExecutionContext jobContext,  int retryCount, bool startsNow)
    {
        var retryInterval = 5;

        var scheduler = StdSchedulerFactory.GetDefaultScheduler();
        // get the trigger

        var intervalReminder = (retryCount == 0 ? 1 : retryCount) * retryInterval;

        var triggerBuilder = jobContext.Trigger.GetTriggerBuilder();

        //crerates a new trigger with the old one
        var newTrigger = triggerBuilder.WithSimpleSchedule(s => s
            .WithIntervalInMinutes(intervalReminder)
            .RepeatForever())
            .Build();

        if (newTrigger is ISimpleTrigger simpleTrigger)
        {
            if (jobContext.JobInstance is ISimpleTrigger trigger)
                (newTrigger as ISimpleTrigger).TimesTriggered = trigger.TimesTriggered;
        }

        // reschedule the job with a new trigger
        scheduler.RescheduleJob(jobContext.Trigger.Key, newTrigger);
        Logger.Warn($"EmailJob Time elapsed updated to {intervalReminder} mins.");

    }
    }

奇怪的是,一段时间后,当重试时间用尽时,它按预期工作。为什么?我不知道。

有人可以帮助我吗? 谢谢。

1 个答案:

答案 0 :(得分:0)

最后,我将代码更改为使用另一列,并存储下一个日期重试间隔。我删除了RescheduleJob,并且当我检查

 var retryIntervals = new[] { 15, 25, 45, 60, 93, 110, 150 };     
var emails = emailsQueue .Where(ml => ml.RetryCount < retryCount && ml.NextTimeRetry <= DateTimeOffset.UtcNow);

我也更改了此部分,以考虑到必须更改重试时间

if (!EmailService.SendEmail(email, out string error))
                    {
email.NextTimeRetry = DateTimeOffset.UtcNow.AddMinutes(retryIntervals[email.RetryCount]);

                        if (email.RetryCount >= retryCount)
                        {
                            Logger.Error($"Email on Queue Reach max {retryCount} send retry Times!");
                        }
                    }

目前没有人回答这个问题,但是对人们知道如何处理这个问题很有帮助。