/// <summary> /// Compare the next fire time of this <see cref="Trigger" /> to that of another. /// </summary> /// <param name="obj"></param> /// <returns></returns> public int CompareTo(object obj) { Trigger other = (Trigger)obj; NullableDateTime myTime = GetNextFireTimeUtc(); NullableDateTime otherTime = other.GetNextFireTimeUtc(); if (!myTime.HasValue && !otherTime.HasValue) { return(0); } if (!myTime.HasValue) { return(1); } if (!otherTime.HasValue) { return(-1); } if ((myTime.Value < otherTime.Value)) { return(-1); } if ((myTime.Value > otherTime.Value)) { return(1); } return(0); }
public int CompareTo(object obj) { Trigger trigger = (Trigger)obj; DateTime?nextFireTimeUtc = this.GetNextFireTimeUtc(); DateTime?nullable2 = trigger.GetNextFireTimeUtc(); if (nextFireTimeUtc.HasValue || nullable2.HasValue) { if (!nextFireTimeUtc.HasValue) { return(1); } if (!nullable2.HasValue) { return(-1); } if (nextFireTimeUtc.Value < nullable2.Value) { return(-1); } if (nextFireTimeUtc.Value > nullable2.Value) { return(1); } } return(0); }
public void TriggeredJobComplete(Trigger trigger, IScheduledJob job, SchedulerInstruction triggerInstCode) { lock (_triggerLock) { JobWrapper jw = _jobsDictionary[job.Name] as JobWrapper; TriggerWrapper tw = _triggersDictionary[trigger.Name] as TriggerWrapper; // even if it was deleted, there may be cleanup to do _blockedJobs.Remove(job.Name); // check for trigger deleted during execution... if (tw != null) { if (triggerInstCode == SchedulerInstruction.DeleteTrigger) { //log.Debug("Deleting trigger"); NullableDateTime d = trigger.GetNextFireTimeUtc(); if (!d.HasValue) { // double check for possible reschedule within job // execution, which would cancel the need to delete... d = tw.Trigger.GetNextFireTimeUtc(); if (!d.HasValue) { RemoveTrigger(trigger.Name); } else { log.Debug("Deleting cancelled - trigger still active"); } } else { RemoveTrigger(trigger.Name); } } else if (triggerInstCode == SchedulerInstruction.SetTriggerComplete) { tw.State = InternalTriggerState.Complete; _timeTriggers.Remove(tw); } else if (triggerInstCode == SchedulerInstruction.SetTriggerError) { log.Info(string.Format(CultureInfo.InvariantCulture, "Trigger {0} set to ERROR state.", trigger.Name)); tw.State = InternalTriggerState.Error; } else if (triggerInstCode == SchedulerInstruction.SetAllJobTriggersError) { log.Info(string.Format(CultureInfo.InvariantCulture, "All triggers of Job {0} set to ERROR state.", trigger.Name)); SetAllTriggersOfJobToState(trigger.Name, InternalTriggerState.Error); } else if (triggerInstCode == SchedulerInstruction.SetAllJobTriggersComplete) { SetAllTriggersOfJobToState(trigger.Name, InternalTriggerState.Complete); } } } }
public void TriggeredJobComplete(Trigger trigger, IScheduledJob job, SchedulerInstruction triggerInstCode) { lock (this._triggerLock) { JobWrapper wrapper = this._jobsDictionary[job.Name] as JobWrapper; TriggerWrapper wrapper2 = this._triggersDictionary[trigger.Name] as TriggerWrapper; this._blockedJobs.Remove(job.Name); if (wrapper2 != null) { if (triggerInstCode == SchedulerInstruction.DeleteTrigger) { if (!trigger.GetNextFireTimeUtc().HasValue) { if (!wrapper2.Trigger.GetNextFireTimeUtc().HasValue) { this.RemoveTrigger(trigger.Name); } else { log.Debug("Deleting cancelled - trigger still active"); } } else { this.RemoveTrigger(trigger.Name); } } else if (triggerInstCode == SchedulerInstruction.SetTriggerComplete) { wrapper2.State = InternalTriggerState.Complete; this._timeTriggers.Remove(wrapper2); } else if (triggerInstCode == SchedulerInstruction.SetTriggerError) { log.Info(string.Format(CultureInfo.InvariantCulture, "Trigger {0} set to ERROR state.", new object[] { trigger.Name })); wrapper2.State = InternalTriggerState.Error; } else if (triggerInstCode == SchedulerInstruction.SetAllJobTriggersError) { log.Info(string.Format(CultureInfo.InvariantCulture, "All triggers of Job {0} set to ERROR state.", new object[] { trigger.Name })); this.SetAllTriggersOfJobToState(trigger.Name, InternalTriggerState.Error); } else if (triggerInstCode == SchedulerInstruction.SetAllJobTriggersComplete) { this.SetAllTriggersOfJobToState(trigger.Name, InternalTriggerState.Complete); } } } }
public TriggerFiredBundle TriggerFired(Trigger trigger) { lock (_triggerLock) { TriggerWrapper tw = _triggersDictionary[trigger.Name] as TriggerWrapper; // was the trigger deleted since being acquired? if (tw == null || tw.Trigger == null) return null; // was the trigger completed since being acquired? if (tw.State == InternalTriggerState.Complete) return null; // was the trigger paused since being acquired? if (tw.State == InternalTriggerState.Paused) return null; // was the trigger blocked since being acquired? if (tw.State == InternalTriggerState.Blocked) return null; // was the trigger paused and blocked since being acquired? if (tw.State == InternalTriggerState.PausedAndBlocked) return null; NullableDateTime prevFireTime = trigger.GetPreviousFireTimeUtc(); // in case trigger was replaced between acquiring and firering _timeTriggers.Remove(tw); trigger.Triggered(); //tw.state = TriggerWrapper.StateExecuting; tw.State = InternalTriggerState.Waiting; IScheduledJob job = RetrieveJob(trigger.JobName); TriggerFiredBundle bndle = new TriggerFiredBundle(job, trigger, false, DateTime.UtcNow, trigger.GetPreviousFireTimeUtc(), prevFireTime, trigger.GetNextFireTimeUtc()); NullableDateTime d = tw.Trigger.GetNextFireTimeUtc(); if (d.HasValue) { lock (_triggerLock) { _timeTriggers.Add(tw); } } return bndle; } }
public TriggerFiredBundle TriggerFired(Trigger trigger) { lock (_triggerLock) { TriggerWrapper tw = _triggersDictionary[trigger.Name] as TriggerWrapper; // was the trigger deleted since being acquired? if (tw == null || tw.Trigger == null) { return(null); } // was the trigger completed since being acquired? if (tw.State == InternalTriggerState.Complete) { return(null); } // was the trigger paused since being acquired? if (tw.State == InternalTriggerState.Paused) { return(null); } // was the trigger blocked since being acquired? if (tw.State == InternalTriggerState.Blocked) { return(null); } // was the trigger paused and blocked since being acquired? if (tw.State == InternalTriggerState.PausedAndBlocked) { return(null); } NullableDateTime prevFireTime = trigger.GetPreviousFireTimeUtc(); // in case trigger was replaced between acquiring and firering _timeTriggers.Remove(tw); trigger.Triggered(); //tw.state = TriggerWrapper.StateExecuting; tw.State = InternalTriggerState.Waiting; IScheduledJob job = RetrieveJob(trigger.JobName); TriggerFiredBundle bndle = new TriggerFiredBundle(job, trigger, false, DateTime.UtcNow, trigger.GetPreviousFireTimeUtc(), prevFireTime, trigger.GetNextFireTimeUtc()); NullableDateTime d = tw.Trigger.GetNextFireTimeUtc(); if (d.HasValue) { lock (_triggerLock) { _timeTriggers.Add(tw); } } return(bndle); } }
/// <summary> /// The main processing loop. /// </summary> public void Run() { bool lastAcquireFailed = false; while (!_halted) { try { // check if we're supposed to pause... lock (_pauseLock) { while (_paused && !_halted) { try { // wait until togglePause(false) is called... Monitor.Wait(_pauseLock, 100); } catch (ThreadInterruptedException) { } } if (_halted) { break; } } int availTreadCount = _threadPool.AvailableThreads; DateTime now; int spinInterval; int numPauses; if (availTreadCount > 0) { Trigger trigger = null; now = DateTime.UtcNow; _signaled = false; try { trigger = AcquireNextTrigger(now.AddMilliseconds(_idleWaitTime)); lastAcquireFailed = false; } catch (Exception e) { if (!lastAcquireFailed) { log.Error("SchedulerThreadLoop: RuntimeException " + e.Message, e); } lastAcquireFailed = true; } if (trigger != null) { now = DateTime.UtcNow; DateTime triggerTime = trigger.GetNextFireTimeUtc().Value; long timeUntilTrigger = (long)(triggerTime - now).TotalMilliseconds; spinInterval = 10; // this looping may seem a bit silly, but it's the // current work-around // for a dead-lock that can occur if the Thread.sleep() // is replaced with // a obj.wait() that gets notified when the signal is // set... // so to be able to detect the signal change without // sleeping the entire // timeUntilTrigger, we spin here... don't worry // though, this spinning // doesn't even register 0.2% cpu usage on a pentium 4. numPauses = (int)(timeUntilTrigger / spinInterval); while (numPauses >= 0 && !_signaled) { try { Thread.Sleep(spinInterval); } catch (ThreadInterruptedException) { } now = DateTime.UtcNow; timeUntilTrigger = (long)(triggerTime - now).TotalMilliseconds; numPauses = (int)(timeUntilTrigger / spinInterval); } if (_signaled) { try { ReleaseAcquiredTrigger(trigger); } catch (Exception ex) { log.Error("ReleaseAcquiredTrigger: RuntimeException " + ex.Message, ex); } _signaled = false; continue; } // set trigger to 'executing' TriggerFiredBundle bundle = null; lock (_pauseLock) { if (!_halted) { try { bundle = TriggerFired(trigger); } catch (Exception ex) { log.Error(string.Format(CultureInfo.InvariantCulture, "RuntimeException while firing trigger {0}", trigger.Name), ex); } } // it's possible to get 'null' if the trigger was paused, // blocked, or other similar occurances that prevent it being // fired at this time... or if the scheduler was shutdown (halted) if (bundle == null) { try { ReleaseAcquiredTrigger(trigger); } catch (SchedulerException) { } continue; } _threadPool.QueueUserWorkItem(new WaitCallback(ProcessJob), bundle); } continue; } } else { // if(availTreadCount > 0) continue; // should never happen, if threadPool.blockForAvailableThreads() follows contract } // this looping may seem a bit silly, but it's the current // work-around // for a dead-lock that can occur if the Thread.sleep() is replaced // with // a obj.wait() that gets notified when the signal is set... // so to be able to detect the signal change without sleeping the // entier // getRandomizedIdleWaitTime(), we spin here... don't worry though, // the // CPU usage of this spinning can't even be measured on a pentium // 4. now = DateTime.UtcNow; DateTime waitTime = now.AddMilliseconds(GetRandomizedIdleWaitTime()); long timeUntilContinue = (long)(waitTime - now).TotalMilliseconds; spinInterval = 10; numPauses = (int)(timeUntilContinue / spinInterval); while (numPauses > 0 && !_signaled) { try { Thread.Sleep(10); } catch (ThreadInterruptedException) { } now = DateTime.UtcNow; timeUntilContinue = (long)(waitTime - now).TotalMilliseconds; numPauses = (int)(timeUntilContinue / spinInterval); } } catch (ThreadAbortException) { } catch (Exception ex) { log.Error("Runtime error occured in main trigger firing loop.", ex); } } }
public TriggerFiredBundle TriggerFired(Trigger trigger) { lock (this._triggerLock) { TriggerWrapper wrapper = this._triggersDictionary[trigger.Name] as TriggerWrapper; if ((wrapper == null) || (wrapper.Trigger == null)) { return(null); } if (wrapper.State == InternalTriggerState.Complete) { return(null); } if (wrapper.State == InternalTriggerState.Paused) { return(null); } if (wrapper.State == InternalTriggerState.Blocked) { return(null); } if (wrapper.State == InternalTriggerState.PausedAndBlocked) { return(null); } DateTime?previousFireTimeUtc = trigger.GetPreviousFireTimeUtc(); this._timeTriggers.Remove(wrapper); trigger.Triggered(); wrapper.State = InternalTriggerState.Waiting; TriggerFiredBundle bundle = new TriggerFiredBundle(this.RetrieveJob(trigger.JobName), trigger, false, new DateTime?(DateTime.UtcNow), trigger.GetPreviousFireTimeUtc(), previousFireTimeUtc, trigger.GetNextFireTimeUtc()); if (wrapper.Trigger.GetNextFireTimeUtc().HasValue) { lock (this._triggerLock) { this._timeTriggers.Add(wrapper); } } return(bundle); } }
public void Run() { bool flag = false; while (!this._halted) { Exception exception2; try { int num2; int num3; object obj2; TimeSpan span; lock ((obj2 = this._pauseLock)) { while (this._paused && !this._halted) { try { Monitor.Wait(this._pauseLock, 100); } catch (ThreadInterruptedException) { } } if (this._halted) { break; } } if (this._threadPool.AvailableThreads <= 0) { continue; } Trigger trigger = null; DateTime utcNow = DateTime.UtcNow; this._signaled = false; try { trigger = this.AcquireNextTrigger(utcNow.AddMilliseconds((double)this._idleWaitTime)); flag = false; } catch (Exception exception) { if (!flag) { log.Error("SchedulerThreadLoop: RuntimeException " + exception.Message, exception); } flag = true; } if (trigger != null) { utcNow = DateTime.UtcNow; DateTime time2 = trigger.GetNextFireTimeUtc().Value; span = (TimeSpan)(time2 - utcNow); long num4 = (long)span.TotalMilliseconds; num2 = 10; num3 = (int)(num4 / ((long)num2)); while ((num3 >= 0) && !this._signaled) { try { Thread.Sleep(num2); } catch (ThreadInterruptedException) { } utcNow = DateTime.UtcNow; span = (TimeSpan)(time2 - utcNow); num4 = (long)span.TotalMilliseconds; num3 = (int)(num4 / ((long)num2)); } if (this._signaled) { try { this.ReleaseAcquiredTrigger(trigger); } catch (Exception exception5) { exception2 = exception5; log.Error("ReleaseAcquiredTrigger: RuntimeException " + exception2.Message, exception2); } this._signaled = false; } else { TriggerFiredBundle state = null; lock ((obj2 = this._pauseLock)) { if (!this._halted) { try { state = this.TriggerFired(trigger); } catch (Exception exception6) { exception2 = exception6; log.Error(string.Format(CultureInfo.InvariantCulture, "RuntimeException while firing trigger {0}", new object[] { trigger.Name }), exception2); } } if (state == null) { try { this.ReleaseAcquiredTrigger(trigger); } catch (SchedulerException) { } } else { this._threadPool.QueueUserWorkItem(new WaitCallback(this.ProcessJob), state); } } } continue; } utcNow = DateTime.UtcNow; DateTime time3 = utcNow.AddMilliseconds((double)this.GetRandomizedIdleWaitTime()); span = (TimeSpan)(time3 - utcNow); long totalMilliseconds = (long)span.TotalMilliseconds; num2 = 10; for (num3 = (int)(totalMilliseconds / ((long)num2)); (num3 > 0) && !this._signaled; num3 = (int)(totalMilliseconds / ((long)num2))) { try { Thread.Sleep(10); } catch (ThreadInterruptedException) { } utcNow = DateTime.UtcNow; span = (TimeSpan)(time3 - utcNow); totalMilliseconds = (long)span.TotalMilliseconds; } } catch (Exception exception9) { exception2 = exception9; log.Error("Runtime error occured in main trigger firing loop.", exception2); } } }