/// <summary> /// Applies the misfire. /// </summary> /// <param name="tw">The trigger wrapper.</param> /// <returns></returns> protected virtual bool ApplyMisfire(IOperableTrigger trigger) { DateTimeOffset misfireTime = SystemTime.UtcNow(); if (MisfireThreshold > TimeSpan.Zero) { misfireTime = misfireTime.AddMilliseconds(-1 * MisfireThreshold.TotalMilliseconds); } DateTimeOffset? tnft = trigger.GetNextFireTimeUtc(); if (!tnft.HasValue || tnft.Value > misfireTime || trigger.MisfireInstruction == MisfireInstruction.IgnoreMisfirePolicy) { return false; } ICalendar cal = null; if (trigger.CalendarName != null) { cal = this.RetrieveCalendar(trigger.CalendarName); } signaler.NotifyTriggerListenersMisfired(trigger); trigger.UpdateAfterMisfire(cal); this.StoreTrigger(trigger, true); if (!trigger.GetNextFireTimeUtc().HasValue) { this.Triggers.Update( Query.EQ("_id", trigger.Key.ToBsonDocument()), Update.Set("State", "Complete")); signaler.NotifySchedulerListenersFinalized(trigger); } else if (tnft.Equals(trigger.GetNextFireTimeUtc())) { return false; } return true; }
/// <summary> /// Determine whether or not the given trigger has misfired.If so, notify {SchedulerSignaler} and update the trigger. /// </summary> /// <param name="trigger">IOperableTrigger</param> /// <returns>applied or not</returns> protected bool ApplyMisfire(IOperableTrigger trigger) { double misfireTime = DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(); double score = misfireTime; if (MisfireThreshold > 0) { misfireTime = misfireTime - MisfireThreshold; } //if the trigger has no next fire time or exceeds the misfirethreshold or enable ignore misfirepolicy // then dont apply misfire. DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc(); if (nextFireTime.HasValue == false || (nextFireTime.HasValue && nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds() > misfireTime) || trigger.MisfireInstruction == -1) { return false; } ICalendar calendar = null; if (!string.IsNullOrEmpty(trigger.CalendarName)) { calendar = RetrieveCalendar(trigger.CalendarName); } SchedulerSignaler.NotifyTriggerListenersMisfired((IOperableTrigger)trigger.Clone()); trigger.UpdateAfterMisfire(calendar); StoreTrigger(trigger, true); if (nextFireTime.HasValue == false) { SetTriggerState(RedisTriggerState.Completed, score, RedisJobStoreSchema.TriggerHashkey(trigger.Key)); SchedulerSignaler.NotifySchedulerListenersFinalized(trigger); } else if (nextFireTime.Equals(trigger.GetNextFireTimeUtc())) { return false; } return true; }
private void DoUpdateOfMisfiredTrigger(ConnectionAndTransactionHolder conn, IOperableTrigger trig, bool forceState, string newStateIfNotComplete, bool recovering) { ICalendar cal = null; if (trig.CalendarName != null) { cal = RetrieveCalendar(conn, trig.CalendarName); } schedSignaler.NotifyTriggerListenersMisfired(trig); trig.UpdateAfterMisfire(cal); if (!trig.GetNextFireTimeUtc().HasValue) { StoreTrigger(conn, trig, null, true, StateComplete, forceState, recovering); schedSignaler.NotifySchedulerListenersFinalized(trig); } else { StoreTrigger(conn, trig, null, true, newStateIfNotComplete, forceState, false); } }
private void DoUpdateOfMisfiredTrigger(IOperableTrigger trig, bool forceState, InternalTriggerState newStateIfNotComplete, bool recovering) { ICalendar cal = null; if (trig.CalendarName != null) { cal = RetrieveCalendar(trig.CalendarName); } signaler.NotifyTriggerListenersMisfired(trig); trig.UpdateAfterMisfire(cal); // TODO: Decide if we need to replace the whole trigger or could just update the status and next-fire-time if (!trig.GetNextFireTimeUtc().HasValue) { StoreTrigger(trig, null, true, InternalTriggerState.Complete, forceState, recovering); } else { StoreTrigger(trig, null, true, newStateIfNotComplete, forceState, false); } }