简体   繁体   中英

How to ignore Misfires in Quartz.Net?

This is my Quartz configuration:

  <quartz>
    <add key="quartz.scheduler.instanceName" value="EmailScheduler" />
    <!-- Configure Thread Pool -->
    <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
    <add key="quartz.threadPool.threadCount" value="10" />
    <add key="quartz.threadPool.threadPriority" value="Normal" />
    <!-- Configure Job Store -->
    <add key="quartz.jobStore.misfireThreshold" value="60000" />
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz" />
    <add key="quartz.jobStore.dataSource" value="default" />
    <add key="quartz.jobStore.lockHandler.type" value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz" />
    <add key="quartz.dataSource.default.provider" value="SqlServer-20" />
    <add key="quartz.dataSource.default.connectionString" value="data source= ......" />
    <add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
  </quartz>

here is my IInterruptableJob :

public class JobC : Quartz.IInterruptableJob
{
    public void Interrupt()
    {
        Console.WriteLine("Job Interrupt() called at " + DateTime.Now);
    }

    public void Execute(IJobExecutionContext context)
    {
        // what code I should write here to detect misfires???
        Console.WriteLine("FireTime at " + context.FireTimeUtc.Value + " PreviousFireTime at:" + (context.PreviousFireTimeUtc.HasValue ? context.PreviousFireTimeUtc.Value.ToString() : "NULL"));
    }
}

Here is my job and trigger:

var job = JobBuilder.Create<JobC>().WithIdentity(new JobKey("JobC")).RequestRecovery(true).Build();
var trigger = TriggerBuilder.Create()
    .WithSimpleSchedule(x => x
        .RepeatForever()
        .WithIntervalInSeconds(2)
            // I'm ignoring misfires here, but seems it doesn't work!
        .WithMisfireHandlingInstructionIgnoreMisfires())
    .StartNow()
    .Build();

var scheduler = new Quartz.Impl.StdSchedulerFactory().GetScheduler();
scheduler.Start();
scheduler.ScheduleJob(job, trigger);

After I call scheduler.PauseAll() all jobs pause and after calling scheduler.ResumeAll() all missed fires, get fired. but I want to ignore them and just continue from now on.

Thanks in advance.

Are you sure your triggers meet the defined misfire threshold? If you have threshold of 60 seconds as you configuration states, every trigger that is not considered misfired but have met their scheduled fire time will be fired as soon as possible after resume.

So you should see the ignore behavior if your pause lasts as least threshold value, which is 60 seconds in this case.

It may seems stupid, but I made following extension method to detect misfires inside Execute method:

public static bool IsMissedFire(this IJobExecutionContext context, int offsetMilliseconds)
{
    if (!context.ScheduledFireTimeUtc.HasValue)
        return false;
    if (!context.FireTimeUtc.HasValue)
        return false;

    var scheduledFireTimeUtc = context.ScheduledFireTimeUtc.Value;
    var fireTimeUtc = context.FireTimeUtc.Value;

    return fireTimeUtc.Subtract(scheduledFireTimeUtc).TotalMilliseconds > offsetMilliseconds;
}

Usage is simple:

public void Execute(IJobExecutionContext context)
{
    if (context.IsMissedFire(1000))
        Console.WriteLine("Missfire");
    else
        Console.WriteLine("Fire");
}

Although it's for the Java version of Quartz, the below link gives a good overview of the different misfire policies:

http://nurkiewicz.blogspot.co.uk/2012/04/quartz-scheduler-misfire-instructions.html

In essence WithMisfireHandlingInstructionIgnoreMisfires actually executes misfires as soon as a thread becomes available, which seems very counter-intuitive. In order to discard all misfires and continue with the schedule you need to use withMisfireHandlingInstructionNextWithRemainingCount.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM