public void EndTimeUtc_GetterAndSetter() { JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, DateTime.UtcNow); details.EndTimeUtc = new DateTime(1970, 1, 2); DateTimeAssert.AreEqualIncludingKind(new DateTime(1970, 1, 2, 0, 0, 0, DateTimeKind.Utc), details.EndTimeUtc); }
public void Succeeded_GetterAndSetter() { JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, DateTime.UtcNow); details.Succeeded = true; Assert.IsTrue(details.Succeeded); }
public void StatusMessage_GetterAndSetter() { JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, DateTime.UtcNow); details.StatusMessage = "Test test test"; Assert.AreEqual("Test test test", details.StatusMessage); }
public void LastJobExecutionDetails_GetterAndSetter() { JobDetails jobDetails = new JobDetails(jobSpec, DateTime.UtcNow); JobExecutionDetails jobExecutionDetails = new JobExecutionDetails(SchedulerGuid, DateTime.UtcNow); jobDetails.LastJobExecutionDetails = jobExecutionDetails; Assert.AreSame(jobExecutionDetails, jobDetails.LastJobExecutionDetails); }
public void ConstructorSetsProperties() { JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, new DateTime(2000, 3, 4)); Assert.AreEqual(SchedulerGuid, details.SchedulerGuid); DateTimeAssert.AreEqualIncludingKind(new DateTime(2000, 3, 4, 0, 0, 0, DateTimeKind.Utc), details.StartTimeUtc); Assert.IsNull(details.EndTimeUtc); Assert.IsFalse(details.Succeeded); Assert.AreEqual("Unknown", details.StatusMessage); }
/// <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); }
public static void AreEqual(JobExecutionDetails expected, JobExecutionDetails actual) { if (expected == null) { Assert.IsNull(actual); return; } Assert.IsNotNull(actual); Assert.AreEqual(expected.SchedulerGuid, actual.SchedulerGuid); AreEqualUpToErrorLimit(expected.StartTimeUtc, actual.StartTimeUtc); AreEqualUpToErrorLimit(expected.EndTimeUtc, actual.EndTimeUtc); Assert.AreEqual(expected.StatusMessage, actual.StatusMessage); Assert.AreEqual(expected.Succeeded, actual.Succeeded); }
public void ClonePerformsADeepCopy(bool useGenericClonable) { DateTime now = DateTime.UtcNow; JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, now); details.EndTimeUtc = new DateTime(2000, 3, 4); details.Succeeded = true; details.StatusMessage = "Blah"; JobExecutionDetails clone = useGenericClonable ? details.Clone() : (JobExecutionDetails) ((ICloneable) details).Clone(); Assert.AreNotSame(details, clone); JobAssert.AreEqual(details, clone); }
public void ClonePerformsADeepCopy(bool useGenericClonable) { DateTime now = DateTime.UtcNow; JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, now); details.EndTimeUtc = new DateTime(2000, 3, 4); details.Succeeded = true; details.StatusMessage = "Blah"; JobExecutionDetails clone = useGenericClonable ? details.Clone() : (JobExecutionDetails)((ICloneable)details).Clone(); Assert.AreNotSame(details, clone); JobAssert.AreEqual(details, clone); }
public JobExecutionDetails GetJobExecutionDetails(string jobName) { var jobExecutionList = _repository.GetByName(jobName); var jobInfo = CalculateJobRunHistory(jobExecutionList); var windowFrameInterval = Threshold * jobInfo.ScheduledInterval; int avgRunTime = 0, numOfOccurence = 0, numberOfMisFires = 0; CalculateMetrics(windowFrameInterval, jobExecutionList, ref avgRunTime, ref numOfOccurence, ref numberOfMisFires); var jobDetails = new JobExecutionDetails { Name = jobInfo.Name, Status = jobInfo.Status, ScheduledInterval = jobInfo.ScheduledInterval, StartTime = DateTime.Now.AddSeconds(-windowFrameInterval), EndTime = DateTime.Now, NumberOfOccurence = numOfOccurence, AverageJobRunTime = avgRunTime, NumberOfMisFires = numberOfMisFires }; return(jobDetails); }
/// <inheritdoc /> public override void UnregisterScheduler(Guid schedulerGuid) { lock (jobs) { ThrowIfDisposed(); // Orphan any jobs that are still running. bool jobsWereOrphaned = false; foreach (VersionedJobDetails job in jobs.Values) { JobExecutionDetails execution = job.LastJobExecutionDetails; if (job.JobState == JobState.Running && execution.SchedulerGuid == schedulerGuid) { job.JobState = JobState.Orphaned; jobsWereOrphaned = true; } } if (jobsWereOrphaned) { SignalBlockedThreads(); } } }
public void StatusMessage_ThrowsIfValueIsNull() { JobExecutionDetails details = new JobExecutionDetails(SchedulerGuid, DateTime.UtcNow); details.StatusMessage = null; }
/// <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; }
/// <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)); } }
/// <summary> /// Saves details for the job. /// </summary> /// <param name="clusterName">The cluster name, never null</param> /// <param name="jobDetails">The job details, never null</param> /// <exception cref="SchedulerException">Thrown if an error occurs</exception> public virtual void SaveJobDetails(string clusterName, VersionedJobDetails jobDetails) { try { using (IDbConnection connection = CreateConnection()) { IDbCommand command = CreateStoredProcedureCommand(connection, "spSCHED_SaveJobDetails"); AddInputParameter(command, "ClusterName", DbType.String, clusterName); AddInputParameter(command, "JobName", DbType.String, jobDetails.JobSpec.Name); AddInputParameter(command, "JobDescription", DbType.String, jobDetails.JobSpec.Description); AddInputParameter(command, "JobKey", DbType.String, jobDetails.JobSpec.JobKey); AddInputParameter(command, "TriggerObject", DbType.Binary, DbUtils.MapObjectToDbValue(DbUtils.SerializeObject(jobDetails.JobSpec.Trigger))); AddInputParameter(command, "JobDataObject", DbType.Binary, DbUtils.MapObjectToDbValue(DbUtils.SerializeObject(jobDetails.JobSpec.JobData))); AddInputParameter(command, "JobState", DbType.Int32, jobDetails.JobState); AddInputParameter(command, "NextTriggerFireTime", DbType.DateTime, DbUtils.MapNullableToDbValue(jobDetails.NextTriggerFireTimeUtc)); int?nextTriggerMisfireThresholdSeconds = jobDetails.NextTriggerMisfireThreshold.HasValue ? (int?)jobDetails.NextTriggerMisfireThreshold.Value.TotalSeconds : null; AddInputParameter(command, "NextTriggerMisfireThresholdSeconds", DbType.Int32, DbUtils.MapNullableToDbValue(nextTriggerMisfireThresholdSeconds)); JobExecutionDetails execution = jobDetails.LastJobExecutionDetails; AddInputParameter(command, "LastExecutionSchedulerGUID", DbType.Guid, execution != null ? (object)execution.SchedulerGuid : DBNull.Value); AddInputParameter(command, "LastExecutionStartTime", DbType.DateTime, execution != null ? (object)execution.StartTimeUtc : DBNull.Value); AddInputParameter(command, "LastExecutionEndTime", DbType.DateTime, execution != null ? DbUtils.MapNullableToDbValue(execution.EndTimeUtc) : DBNull.Value); AddInputParameter(command, "LastExecutionSucceeded", DbType.Boolean, execution != null ? (object)execution.Succeeded : DBNull.Value); AddInputParameter(command, "LastExecutionStatusMessage", DbType.String, execution != null ? (object)execution.StatusMessage : DBNull.Value); AddInputParameter(command, "Version", DbType.Int32, jobDetails.Version); IDbDataParameter wasSavedParam = AddOutputParameter(command, "WasSaved", DbType.Boolean); connection.Open(); command.ExecuteNonQuery(); bool wasSaved = (bool)wasSavedParam.Value; if (!wasSaved) { throw new ConcurrentModificationException( String.Format("Job '{0}' does not exist or was concurrently modified in the database.", jobDetails.JobSpec.Name)); } jobDetails.Version += 1; } } catch (Exception ex) { throw new SchedulerException("The job store was unable to save job details to the database.", ex); } }