/// <summary> /// Called by the scheduler at the time a <see cref="Trigger" /> is first /// added to the scheduler, in order to have the <see cref="Trigger" /> /// compute its first fire time, based on any associated calendar. /// <p> /// After this method has been called, <see cref="GetNextFireTimeUtc" /> /// should return a valid answer. /// </p> /// </summary> /// <returns> /// The first time at which the <see cref="Trigger" /> will be fired /// by the scheduler, which is also the same value <see cref="GetNextFireTimeUtc" /> /// will return (until after the first firing of the <see cref="Trigger" />). /// </returns> public override DateTime?ComputeFirstFireTimeUtc(ICalendar cal) { nextFireTimeUtc = ComputeNextZmanTime(StartTimeUtc); while (nextFireTimeUtc.HasValue && cal != null && !cal.IsTimeIncluded(nextFireTimeUtc.Value)) { nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); if (!nextFireTimeUtc.HasValue) { break; } //avoid infinite loop if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt) { return(null); } } return(nextFireTimeUtc); }
/// <summary> /// Called when the <see cref="IScheduler" /> has decided to 'fire' /// the trigger (Execute the associated <see cref="IJob" />), in order to /// give the <see cref="Trigger" /> a chance to update itself for its next /// triggering (if any). /// </summary> /// <seealso cref="JobExecutionException" /> public override void Triggered(ICalendar cal) { timesTriggered++; previousFireTimeUtc = nextFireTimeUtc; nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); while (nextFireTimeUtc.HasValue && cal != null && !cal.IsTimeIncluded(nextFireTimeUtc.Value)) { nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); if (!nextFireTimeUtc.HasValue) { break; } //avoid infinite loop if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt) { nextFireTimeUtc = null; } } }
/// <summary> /// Updates the instance with new calendar. /// </summary> /// <param name="calendar">The calendar.</param> /// <param name="misfireThreshold">The misfire threshold.</param> public override void UpdateWithNewCalendar(ICalendar calendar, TimeSpan misfireThreshold) { nextFireTimeUtc = GetFireTimeAfter(previousFireTimeUtc); if (nextFireTimeUtc == null || calendar == null) { return; } DateTime now = DateTime.UtcNow; while (nextFireTimeUtc.HasValue && !calendar.IsTimeIncluded(nextFireTimeUtc.Value)) { nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); if (!nextFireTimeUtc.HasValue) { break; } //avoid infinite loop if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt) { nextFireTimeUtc = null; } if (nextFireTimeUtc != null && nextFireTimeUtc.Value < now) { TimeSpan diff = now - nextFireTimeUtc.Value; if (diff >= misfireThreshold) { nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); } } } }
public override void UpdateWithNewCalendar(ICalendar cal, TimeSpan misfireThreshold) { _nextFireTimeUtc = GetFireTimeAfter(_previousFireTimeUtc); if (!_nextFireTimeUtc.HasValue || cal == null) return; var utcNow = TimeProvider.UtcNow; while (_nextFireTimeUtc.HasValue && !cal.IsTimeIncluded(_nextFireTimeUtc.Value)) { _nextFireTimeUtc = GetFireTimeAfter(_nextFireTimeUtc); if (!_nextFireTimeUtc.HasValue) break; if (_nextFireTimeUtc.Value.Year > 2299) _nextFireTimeUtc = new DateTime?(); if (_nextFireTimeUtc.HasValue && _nextFireTimeUtc.Value < utcNow && utcNow - _nextFireTimeUtc.Value >= misfireThreshold) _nextFireTimeUtc = GetFireTimeAfter(_nextFireTimeUtc); } }
/// <summary> /// Updates the after misfire. /// </summary> /// <param name="cal">The cal.</param> public override void UpdateAfterMisfire(ICalendar cal) { var misfireInstruction = MisfireInstruction; if (misfireInstruction == 0) misfireInstruction = FireOnceNow; if (misfireInstruction == DoNothing) { var fireTimeAfter = GetFireTimeAfter(TimeProvider.UtcNow, cal); _nextFireTimeUtc = TimeHelpers.AssumeUniversalTime(fireTimeAfter); } if (misfireInstruction == FireOnceNow) { _nextFireTimeUtc = TimeHelpers.AssumeUniversalTime(TimeProvider.UtcNow); } }
/// <summary> /// Gets the fire time after. /// </summary> /// <param name="afterTime">The after time.</param> /// <param name="calendar">The calendar.</param> /// <returns>System.Nullable{DateTime}.</returns> public DateTime? GetFireTimeAfter(DateTime? afterTime, ICalendar calendar) { var nextFireTime = GetFireTimeAfter(afterTime); if (calendar == null) return nextFireTime; while (nextFireTime.HasValue && !calendar.IsTimeIncluded(nextFireTime.Value)) { nextFireTime = GetFireTimeAfter(nextFireTime); if (nextFireTime.HasValue && nextFireTime.Value.Year > 2299) nextFireTime = null; } return nextFireTime; }
/// <summary> /// Computes the first fire time UTC. /// </summary> /// <param name="cal">The cal.</param> /// <returns>System.Nullable{DateTime}.</returns> public override DateTime? ComputeFirstFireTimeUtc(ICalendar cal) { _nextFireTimeUtc = GetFireTimeAfter(StartTimeUtc, cal); return _nextFireTimeUtc; }
/// <summary> /// Triggereds the specified cal. /// </summary> /// <param name="cal">The cal.</param> public override void Triggered(ICalendar cal) { _previousFireTimeUtc = _nextFireTimeUtc; _nextFireTimeUtc = GetFireTimeAfter(_nextFireTimeUtc, cal); }
/// <summary> /// Updates the <see cref="ZmanimTrigger" />'s state based on the /// MisfireInstruction value that was selected when the <see cref="ZmanimTrigger" /> /// was created. /// </summary> /// <remarks> /// If MisfireSmartPolicyEnabled is set to true, /// then the following scheme will be used: <br /> /// <ul> /// <li>If the Repeat Count is 0, then the instruction will /// be interpreted as <see cref="MisfireInstruction.SimpleTrigger.FireNow" />.</li> /// <li>If the Repeat Count is <see cref="RepeatIndefinitely" />, then /// the instruction will be interpreted as <see cref="MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount" />. /// <b>WARNING:</b> using MisfirePolicy.ZmanimTrigger.RescheduleNowWithRemainingRepeatCount /// with a trigger that has a non-null end-time may cause the trigger to /// never fire again if the end-time arrived during the misfire time span. /// </li> /// <li>If the Repeat Count is > 0, then the instruction /// will be interpreted as <see cref="MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount" />. /// </li> /// </ul> /// </remarks> public override void UpdateAfterMisfire(ICalendar cal) { int instr = MisfireInstruction; if (instr == Quartz.MisfireInstruction.SmartPolicy) { if (RepeatCount == 0) { instr = Quartz.MisfireInstruction.SimpleTrigger.FireNow; } else if (RepeatCount == RepeatIndefinitely) { instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount; } else { instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount; } } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.FireNow && RepeatCount != 0) { instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount; } if (instr == Quartz.MisfireInstruction.SimpleTrigger.FireNow) { SetNextFireTime(DateTime.UtcNow); } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithExistingCount) { DateTime?newFireTime = GetFireTimeAfter(DateTime.UtcNow); while (newFireTime.HasValue && cal != null && !cal.IsTimeIncluded(newFireTime.Value)) { newFireTime = GetFireTimeAfter(newFireTime); if (!newFireTime.HasValue) { break; } //avoid infinite loop if (newFireTime.Value.Year > YearToGiveupSchedulingAt) { newFireTime = null; } } SetNextFireTime(newFireTime); } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount) { DateTime?newFireTime = GetFireTimeAfter(DateTime.UtcNow); while (newFireTime.HasValue && cal != null && !cal.IsTimeIncluded(newFireTime.Value)) { newFireTime = GetFireTimeAfter(newFireTime); if (!newFireTime.HasValue) { break; } //avoid infinite loop if (newFireTime.Value.Year > YearToGiveupSchedulingAt) { newFireTime = null; } } if (newFireTime.HasValue) { int timesMissed = ComputeNumTimesFiredBetween(nextFireTimeUtc, newFireTime); TimesTriggered = TimesTriggered + timesMissed; } SetNextFireTime(newFireTime); } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount) { DateTime newFireTime = DateTime.UtcNow; if (repeatCount != 0 && repeatCount != RepeatIndefinitely) { RepeatCount = RepeatCount - TimesTriggered; TimesTriggered = 0; } if (EndTimeUtc.HasValue && EndTimeUtc.Value < newFireTime) { SetNextFireTime(null); // We are past the end time } else { StartTimeUtc = newFireTime; SetNextFireTime(newFireTime); } } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount) { DateTime newFireTime = DateTime.UtcNow; int timesMissed = ComputeNumTimesFiredBetween(nextFireTimeUtc, newFireTime); if (repeatCount != 0 && repeatCount != RepeatIndefinitely) { int remainingCount = RepeatCount - (TimesTriggered + timesMissed); if (remainingCount <= 0) { remainingCount = 0; } RepeatCount = remainingCount; TimesTriggered = 0; } if (EndTimeUtc.HasValue && EndTimeUtc.Value < newFireTime) { SetNextFireTime(null); // We are past the end time } else { StartTimeUtc = newFireTime; SetNextFireTime(newFireTime); } } }
/// <summary> /// Updates the <see cref="ZmanimTrigger" />'s state based on the /// MisfireInstruction value that was selected when the <see cref="ZmanimTrigger" /> /// was created. /// </summary> /// <remarks> /// If MisfireSmartPolicyEnabled is set to true, /// then the following scheme will be used: <br /> /// <ul> /// <li>If the Repeat Count is 0, then the instruction will /// be interpreted as <see cref="MisfireInstruction.SimpleTrigger.FireNow" />.</li> /// <li>If the Repeat Count is <see cref="RepeatIndefinitely" />, then /// the instruction will be interpreted as <see cref="MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount" />. /// <b>WARNING:</b> using MisfirePolicy.ZmanimTrigger.RescheduleNowWithRemainingRepeatCount /// with a trigger that has a non-null end-time may cause the trigger to /// never fire again if the end-time arrived during the misfire time span. /// </li> /// <li>If the Repeat Count is > 0, then the instruction /// will be interpreted as <see cref="MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount" />. /// </li> /// </ul> /// </remarks> public override void UpdateAfterMisfire(ICalendar cal) { int instr = MisfireInstruction; if (instr == Quartz.MisfireInstruction.SmartPolicy) { if (RepeatCount == 0) { instr = Quartz.MisfireInstruction.SimpleTrigger.FireNow; } else if (RepeatCount == RepeatIndefinitely) { instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount; } else { instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount; } } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.FireNow && RepeatCount != 0) { instr = Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount; } if (instr == Quartz.MisfireInstruction.SimpleTrigger.FireNow) { SetNextFireTime(DateTime.UtcNow); } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithExistingCount) { DateTime? newFireTime = GetFireTimeAfter(DateTime.UtcNow); while (newFireTime.HasValue && cal != null && !cal.IsTimeIncluded(newFireTime.Value)) { newFireTime = GetFireTimeAfter(newFireTime); if (!newFireTime.HasValue) { break; } //avoid infinite loop if (newFireTime.Value.Year > YearToGiveupSchedulingAt) { newFireTime = null; } } SetNextFireTime(newFireTime); } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNextWithRemainingCount) { DateTime? newFireTime = GetFireTimeAfter(DateTime.UtcNow); while (newFireTime.HasValue && cal != null && !cal.IsTimeIncluded(newFireTime.Value)) { newFireTime = GetFireTimeAfter(newFireTime); if (!newFireTime.HasValue) { break; } //avoid infinite loop if (newFireTime.Value.Year > YearToGiveupSchedulingAt) { newFireTime = null; } } if (newFireTime.HasValue) { int timesMissed = ComputeNumTimesFiredBetween(nextFireTimeUtc, newFireTime); TimesTriggered = TimesTriggered + timesMissed; } SetNextFireTime(newFireTime); } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithExistingRepeatCount) { DateTime newFireTime = DateTime.UtcNow; if (repeatCount != 0 && repeatCount != RepeatIndefinitely) { RepeatCount = RepeatCount - TimesTriggered; TimesTriggered = 0; } if (EndTimeUtc.HasValue && EndTimeUtc.Value < newFireTime) { SetNextFireTime(null); // We are past the end time } else { StartTimeUtc = newFireTime; SetNextFireTime(newFireTime); } } else if (instr == Quartz.MisfireInstruction.SimpleTrigger.RescheduleNowWithRemainingRepeatCount) { DateTime newFireTime = DateTime.UtcNow; int timesMissed = ComputeNumTimesFiredBetween(nextFireTimeUtc, newFireTime); if (repeatCount != 0 && repeatCount != RepeatIndefinitely) { int remainingCount = RepeatCount - (TimesTriggered + timesMissed); if (remainingCount <= 0) { remainingCount = 0; } RepeatCount = remainingCount; TimesTriggered = 0; } if (EndTimeUtc.HasValue && EndTimeUtc.Value < newFireTime) { SetNextFireTime(null); // We are past the end time } else { StartTimeUtc = newFireTime; SetNextFireTime(newFireTime); } } }
/// <summary> /// Called by the scheduler at the time a <see cref="Trigger" /> is first /// added to the scheduler, in order to have the <see cref="Trigger" /> /// compute its first fire time, based on any associated calendar. /// <p> /// After this method has been called, <see cref="GetNextFireTimeUtc" /> /// should return a valid answer. /// </p> /// </summary> /// <returns> /// The first time at which the <see cref="Trigger" /> will be fired /// by the scheduler, which is also the same value <see cref="GetNextFireTimeUtc" /> /// will return (until after the first firing of the <see cref="Trigger" />). /// </returns> public override DateTime? ComputeFirstFireTimeUtc(ICalendar cal) { nextFireTimeUtc = ComputeNextZmanTime(StartTimeUtc); while (nextFireTimeUtc.HasValue && cal != null && !cal.IsTimeIncluded(nextFireTimeUtc.Value)) { nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); if (!nextFireTimeUtc.HasValue) { break; } //avoid infinite loop if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt) { return null; } } return nextFireTimeUtc; }