Example #1
0
        /// <summary>
        /// Creates job execution details.
        /// </summary>
        /// <param name="schedulerGuid">The Guid of the scheduler that is running the job</param>
        /// <param name="startTimeUtc">The UTC start time</param>
        public JobExecutionDetails(Guid schedulerGuid, DateTime startTimeUtc)
        {
            this.schedulerGuid = schedulerGuid;
            this.startTimeUtc  = DateTimeUtils.AssumeUniversalTime(startTimeUtc);

            statusMessage = "Unknown";
        }
        /// <summary>
        /// Gets the next job to process for the specified scheduler.
        /// </summary>
        /// <param name="clusterName">The cluster name, never null</param>
        /// <param name="schedulerGuid">The scheduler GUID</param>
        /// <param name="timeBasisUtc">The UTC time to consider as "now"</param>
        /// <param name="nextTriggerFireTimeUtc">Set to the UTC next trigger fire time, or null if there are
        /// no triggers currently scheduled to fire</param>
        /// <param name="schedulerExpirationTimeInSeconds">The scheduler expiration time in seconds, always greater than zero</param>
        /// <returns>The details of job to process or null if none</returns>
        /// <exception cref="SchedulerException">Thrown if an error occurs</exception>
        public virtual VersionedJobDetails GetNextJobToProcess(string clusterName, Guid schedulerGuid, DateTime timeBasisUtc,
                                                               int schedulerExpirationTimeInSeconds,
                                                               out DateTime?nextTriggerFireTimeUtc)
        {
            try
            {
                using (IDbConnection connection = CreateConnection())
                {
                    IDbCommand command = CreateStoredProcedureCommand(connection, "spSCHED_GetNextJobToProcess");

                    AddInputParameter(command, "ClusterName", DbType.String, clusterName);
                    AddInputParameter(command, "SchedulerGUID", DbType.Guid, schedulerGuid);
                    AddInputParameter(command, "TimeBasis", DbType.DateTime, timeBasisUtc);
                    AddInputParameter(command, "SchedulerExpirationTimeInSeconds", DbType.Int32, schedulerExpirationTimeInSeconds);
                    IDbDataParameter nextTriggerFireTimeParam = AddOutputParameter(command, "NextTriggerFireTime", DbType.DateTime);

                    connection.Open();

                    VersionedJobDetails jobDetails;
                    using (IDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult | CommandBehavior.SingleRow))
                    {
                        jobDetails = reader.Read() ? BuildJobDetailsFromResultSet(reader) : null;
                    }

                    nextTriggerFireTimeUtc =
                        DateTimeUtils.AssumeUniversalTime(DbUtils.MapDbValueToNullable <DateTime>(nextTriggerFireTimeParam.Value));
                    return(jobDetails);
                }
            }
            catch (Exception ex)
            {
                throw new SchedulerException(
                          "The job store was unable to get job details for the next job to process from the database.", ex);
            }
        }
Example #3
0
        public virtual int ComputeNumTimesFiredBetween(DateTime?startTimeUtc, DateTime?endTimeUtc)
        {
            startTimeUtc = DateTimeUtils.AssumeUniversalTime(startTimeUtc);
            endTimeUtc   = DateTimeUtils.AssumeUniversalTime(endTimeUtc);
            TimeSpan span = endTimeUtc.Value - startTimeUtc.Value;
            long     totalMilliseconds = (long)span.TotalMilliseconds;

            return((int)(totalMilliseconds / this._repeatInterval));
        }
Example #4
0
        /// <summary>
        /// Computes the number of times fired between the two UTC date times.
        /// </summary>
        /// <param name="startTimeUtc">The UTC start date and time.</param>
        /// <param name="endTimeUtc">The UTC end date and time.</param>
        /// <returns></returns>
        public virtual int ComputeNumTimesFiredBetween(NullableDateTime startTimeUtc, NullableDateTime endTimeUtc)
        {
            startTimeUtc = DateTimeUtils.AssumeUniversalTime(startTimeUtc);
            endTimeUtc   = DateTimeUtils.AssumeUniversalTime(endTimeUtc);

            long time = (long)(endTimeUtc.Value - startTimeUtc.Value).TotalMilliseconds;

            return((int)(time / _repeatInterval));
        }
        /// <summary>
        /// Creates job details for a newly created job.
        /// </summary>
        /// <param name="jobSpec">The job's specification</param>
        /// <param name="creationTimeUtc">The UTC time when the job was created</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="jobSpec"/> is null</exception>
        public JobDetails(JobSpec jobSpec, DateTime creationTimeUtc)
        {
            if (jobSpec == null)
            {
                throw new ArgumentNullException("jobSpec");
            }

            this.jobSpec         = jobSpec;
            this.creationTimeUtc = DateTimeUtils.AssumeUniversalTime(creationTimeUtc);
        }
Example #6
0
 public TriggerFiredBundle(IScheduledJob job, FluorineFx.Scheduling.Trigger trigger, bool jobIsRecovering, DateTime?fireTimeUtc, DateTime?scheduledFireTimeUtc, DateTime?prevFireTimeUtc, DateTime?nextFireTimeUtc)
 {
     this._job                  = job;
     this._trigger              = trigger;
     this._jobIsRecovering      = jobIsRecovering;
     this._fireTimeUtc          = DateTimeUtils.AssumeUniversalTime(fireTimeUtc);
     this._scheduledFireTimeUtc = DateTimeUtils.AssumeUniversalTime(scheduledFireTimeUtc);
     this._prevFireTimeUtc      = DateTimeUtils.AssumeUniversalTime(prevFireTimeUtc);
     this._nextFireTimeUtc      = DateTimeUtils.AssumeUniversalTime(nextFireTimeUtc);
 }
Example #7
0
        public virtual DateTime?GetFireTimeBefore(DateTime?endUtc)
        {
            endUtc = DateTimeUtils.AssumeUniversalTime(endUtc);
            if (endUtc.Value < this.StartTimeUtc)
            {
                return(null);
            }
            int num = this.ComputeNumTimesFiredBetween(new DateTime?(this.StartTimeUtc), endUtc);

            return(new DateTime?(this.StartTimeUtc.AddMilliseconds((double)(num * this._repeatInterval))));
        }
Example #8
0
        /// <summary>
        /// Returns the next UTC time at which the <see cref="Trigger" /> will
        /// fire, after the given UTC time. If the trigger will not fire after the given
        /// time, <see langword="null" /> will be returned.
        /// </summary>
        public NullableDateTime GetFireTimeAfter(NullableDateTime afterTimeUtc)
        {
            afterTimeUtc = DateTimeUtils.AssumeUniversalTime(afterTimeUtc);

            if (_complete)
            {
                return(null);
            }

            if ((_timesTriggered > _repeatCount) && (_repeatCount != RepeatIndefinitely))
            {
                return(null);
            }

            if (!afterTimeUtc.HasValue)
            {
                afterTimeUtc = DateTime.UtcNow;
            }

            if (_repeatCount == 0 && afterTimeUtc.Value.CompareTo(StartTimeUtc) >= 0)
            {
                return(null);
            }

            DateTime startMillis = StartTimeUtc;
            DateTime afterMillis = afterTimeUtc.Value;
            DateTime endMillis   = !EndTimeUtc.HasValue ? DateTime.MaxValue : EndTimeUtc.Value;

            if (endMillis <= afterMillis)
            {
                return(null);
            }

            if (afterMillis < startMillis)
            {
                return(startMillis);
            }

            long numberOfTimesExecuted = ((long)(afterMillis - startMillis).TotalMilliseconds / _repeatInterval) + 1;

            if ((numberOfTimesExecuted > _repeatCount) && (_repeatCount != RepeatIndefinitely))
            {
                return(null);
            }

            DateTime time = startMillis.AddMilliseconds(numberOfTimesExecuted * _repeatInterval);

            if (endMillis <= time)
            {
                return(null);
            }

            return(time);
        }
Example #9
0
        /// <summary>
        /// Returns the last UTC time at which the <see cref="Trigger" /> will
        /// fire, before the given time. If the trigger will not fire before the
        /// given time, <see langword="null" /> will be returned.
        /// </summary>
        public virtual NullableDateTime GetFireTimeBefore(NullableDateTime endUtc)
        {
            endUtc = DateTimeUtils.AssumeUniversalTime(endUtc);
            if (endUtc.Value < StartTimeUtc)
            {
                return(null);
            }

            int numFires = ComputeNumTimesFiredBetween(StartTimeUtc, endUtc);

            return(StartTimeUtc.AddMilliseconds(numFires * _repeatInterval));
        }
        /// <summary>
        /// Builds a job details object from the result set returned by the spSCHED_GetJobDetails
        /// and spSCHED_GetNextJob stored procedures.
        /// </summary>
        /// <param name="reader">The reader for the result set</param>
        /// <returns>The job details object</returns>
        protected virtual VersionedJobDetails BuildJobDetailsFromResultSet(IDataReader reader)
        {
            string  jobName        = reader.GetString(0);
            string  jobDescription = reader.GetString(1);
            string  jobKey         = reader.GetString(2);
            Trigger trigger        = (Trigger)DbUtils.DeserializeObject(DbUtils.MapDbValueToObject <byte[]>(reader.GetValue(3)));

            JobData  jobData                = (JobData)DbUtils.DeserializeObject(DbUtils.MapDbValueToObject <byte[]>(reader.GetValue(4)));
            DateTime creationTimeUtc        = DateTimeUtils.AssumeUniversalTime(reader.GetDateTime(5));
            JobState jobState               = (JobState)reader.GetInt32(6);
            DateTime?nextTriggerFireTimeUtc =
                DateTimeUtils.AssumeUniversalTime(DbUtils.MapDbValueToNullable <DateTime>(reader.GetValue(7)));
            int?     nextTriggerMisfireThresholdSeconds = DbUtils.MapDbValueToNullable <int>(reader.GetValue(8));
            TimeSpan?nextTriggerMisfireThreshold        = nextTriggerMisfireThresholdSeconds.HasValue
                                                                        ?
                                                          new TimeSpan(0, 0, nextTriggerMisfireThresholdSeconds.Value)
                                                                        : (TimeSpan?)null;

            Guid?    lastExecutionSchedulerGuid = DbUtils.MapDbValueToNullable <Guid>(reader.GetValue(9));
            DateTime?lastExecutionStartTimeUtc  =
                DateTimeUtils.AssumeUniversalTime(DbUtils.MapDbValueToNullable <DateTime>(reader.GetValue(10)));
            DateTime?lastExecutionEndTimeUtc =
                DateTimeUtils.AssumeUniversalTime(DbUtils.MapDbValueToNullable <DateTime>(reader.GetValue(11)));
            bool?  lastExecutionSucceeded     = DbUtils.MapDbValueToNullable <bool>(reader.GetValue(12));
            string lastExecutionStatusMessage = DbUtils.MapDbValueToObject <string>(reader.GetValue(13));

            int version = reader.GetInt32(14);

            JobSpec jobSpec = new JobSpec(jobName, jobDescription, jobKey, trigger);

            jobSpec.JobData = jobData;

            VersionedJobDetails details = new VersionedJobDetails(jobSpec, creationTimeUtc, version);

            details.JobState = jobState;
            details.NextTriggerFireTimeUtc      = nextTriggerFireTimeUtc;
            details.NextTriggerMisfireThreshold = nextTriggerMisfireThreshold;

            if (lastExecutionSchedulerGuid.HasValue && lastExecutionStartTimeUtc.HasValue)
            {
                JobExecutionDetails execution = new JobExecutionDetails(lastExecutionSchedulerGuid.Value,
                                                                        lastExecutionStartTimeUtc.Value);
                execution.EndTimeUtc    = lastExecutionEndTimeUtc;
                execution.Succeeded     = lastExecutionSucceeded.GetValueOrDefault();
                execution.StatusMessage = lastExecutionStatusMessage == null ? "" : lastExecutionStatusMessage;

                details.LastJobExecutionDetails = execution;
            }

            return(details);
        }
Example #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TriggerFiredBundle"/> class.
 /// </summary>
 /// <param name="job">The job.</param>
 /// <param name="trigger">The trigger.</param>
 /// <param name="jobIsRecovering">if set to <c>true</c> [job is recovering].</param>
 /// <param name="fireTimeUtc">The fire time.</param>
 /// <param name="scheduledFireTimeUtc">The scheduled fire time.</param>
 /// <param name="prevFireTimeUtc">The previous fire time.</param>
 /// <param name="nextFireTimeUtc">The next fire time.</param>
 public TriggerFiredBundle(IScheduledJob job, Trigger trigger, bool jobIsRecovering,
                           NullableDateTime fireTimeUtc,
                           NullableDateTime scheduledFireTimeUtc,
                           NullableDateTime prevFireTimeUtc,
                           NullableDateTime nextFireTimeUtc)
 {
     _job                  = job;
     _trigger              = trigger;
     _jobIsRecovering      = jobIsRecovering;
     _fireTimeUtc          = DateTimeUtils.AssumeUniversalTime(fireTimeUtc);
     _scheduledFireTimeUtc = DateTimeUtils.AssumeUniversalTime(scheduledFireTimeUtc);
     _prevFireTimeUtc      = DateTimeUtils.AssumeUniversalTime(prevFireTimeUtc);
     _nextFireTimeUtc      = DateTimeUtils.AssumeUniversalTime(nextFireTimeUtc);
 }
Example #12
0
        public DateTime?GetFireTimeAfter(DateTime?afterTimeUtc)
        {
            afterTimeUtc = DateTimeUtils.AssumeUniversalTime(afterTimeUtc);
            if (this._complete)
            {
                return(null);
            }
            if ((this._timesTriggered > this._repeatCount) && (this._repeatCount != -1))
            {
                return(null);
            }
            if (!afterTimeUtc.HasValue)
            {
                afterTimeUtc = new DateTime?(DateTime.UtcNow);
            }
            if ((this._repeatCount == 0) && (afterTimeUtc.Value.CompareTo(this.StartTimeUtc) >= 0))
            {
                return(null);
            }
            DateTime startTimeUtc = this.StartTimeUtc;
            DateTime time2        = afterTimeUtc.Value;
            DateTime?endTimeUtc   = this.EndTimeUtc;
            DateTime time3        = !endTimeUtc.HasValue ? DateTime.MaxValue : (endTimeUtc = this.EndTimeUtc).Value;

            if (time3 <= time2)
            {
                return(null);
            }
            if (time2 < startTimeUtc)
            {
                return(new DateTime?(startTimeUtc));
            }
            TimeSpan span = (TimeSpan)(time2 - startTimeUtc);
            long     num  = (((long)span.TotalMilliseconds) / this._repeatInterval) + 1L;

            if ((num > this._repeatCount) && (this._repeatCount != -1))
            {
                return(null);
            }
            DateTime time4 = startTimeUtc.AddMilliseconds((double)(num * this._repeatInterval));

            if (time3 <= time4)
            {
                return(null);
            }
            return(new DateTime?(time4));
        }
        /// <summary>
        /// Creates a periodic trigger.
        /// </summary>
        /// <param name="startTimeUtc">The UTC date and time when the trigger will first fire</param>
        /// <param name="endTimeUtc">The UTC date and time when the trigger must stop firing.
        /// If the time is set to null, the trigger may continue firing indefinitely.</param>
        /// <param name="period">The recurrence period of the trigger.
        /// If the period is set to null, the trigger will fire exactly once
        /// and never recur.</param>
        /// <param name="jobExecutionCount">The number of job executions remaining before the trigger
        /// stops firing.  This number is decremented each time the job executes
        /// until it reaches zero.  If the count is set to null, the number of times the job
        /// may execute is unlimited.</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="period"/> is negative or zero</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="jobExecutionCount"/> is negative</exception>
        public PeriodicTrigger(DateTime startTimeUtc, DateTime?endTimeUtc, TimeSpan?period, int?jobExecutionCount)
        {
            if (period.HasValue && period.Value.Ticks <= 0)
            {
                throw new ArgumentOutOfRangeException("period", "The recurrence period must not be negative or zero.");
            }
            if (jobExecutionCount.HasValue && jobExecutionCount.Value < 0)
            {
                throw new ArgumentOutOfRangeException("jobExecutionCount", "The job execution count remaining must not be negative.");
            }

            this.startTimeUtc          = DateTimeUtils.AssumeUniversalTime(startTimeUtc);
            this.endTimeUtc            = DateTimeUtils.AssumeUniversalTime(endTimeUtc);
            this.period                = period;
            jobExecutionCountRemaining = jobExecutionCount;
            isFirstTime                = true;

            misfireAction = DefaultMisfireAction;
        }
        /// <inheritdoc />
        public override TriggerScheduleAction Schedule(TriggerScheduleCondition condition, DateTime timeBasisUtc,
                                                       JobExecutionDetails lastJobExecutionDetails)
        {
            timeBasisUtc = DateTimeUtils.AssumeUniversalTime(timeBasisUtc);

            switch (condition)
            {
            case TriggerScheduleCondition.Latch:
                return(ScheduleSuggestedAction(TriggerScheduleAction.Skip, timeBasisUtc));

            case TriggerScheduleCondition.Misfire:
                isFirstTime = false;
                return(ScheduleSuggestedAction(misfireAction, timeBasisUtc));

            case TriggerScheduleCondition.Fire:
                isFirstTime = false;
                return(ScheduleSuggestedAction(TriggerScheduleAction.ExecuteJob, timeBasisUtc));

            default:
                throw new SchedulerException(String.Format(CultureInfo.CurrentCulture,
                                                           "Unrecognized trigger schedule condition '{0}'.", condition));
            }
        }
Example #15
0
 /// <summary>
 /// Set the previous UTC time at which the <see cref="SimpleTrigger" /> fired.
 /// <strong>This method should not be invoked by client code.</strong>
 /// </summary>
 public virtual void SetPreviousFireTime(NullableDateTime fireTimeUtc)
 {
     _previousFireTimeUtc = DateTimeUtils.AssumeUniversalTime(fireTimeUtc);
 }
 public void AssumeUniversalTime_NonNull()
 {
     DateTimeAssert.AreEqualIncludingKind(new DateTime(2000, 3, 4, 0, 0, 0, DateTimeKind.Utc),
                                          DateTimeUtils.AssumeUniversalTime((DateTime?)new DateTime(2000, 3, 4)));
 }
Example #17
0
 public void SetNextFireTime(DateTime?fireTimeUtc)
 {
     this._nextFireTimeUtc = DateTimeUtils.AssumeUniversalTime(fireTimeUtc);
 }
Example #18
0
 public virtual void SetPreviousFireTime(DateTime?fireTimeUtc)
 {
     this._previousFireTimeUtc = DateTimeUtils.AssumeUniversalTime(fireTimeUtc);
 }
 public void AssumeUniversalTime_Null()
 {
     Assert.IsNull(DateTimeUtils.AssumeUniversalTime(null));
 }
Example #20
0
 /// <summary>
 /// Set the next UTC time at which the <see cref="SimpleTrigger" /> should fire.
 /// <strong>This method should not be invoked by client code.</strong>
 /// </summary>
 public void SetNextFireTime(NullableDateTime fireTimeUtc)
 {
     _nextFireTimeUtc = DateTimeUtils.AssumeUniversalTime(fireTimeUtc);
 }