using Disco.Data.Repository; using Quartz; using System; namespace Disco.Services.Tasks { public abstract class ScheduledTask : IJob { public virtual void InitalizeScheduledTask(DiscoDataContext Database) { return; } internal protected ScheduledTaskStatus Status { get; private set; } internal protected IJobExecutionContext ExecutionContext { get; private set; } public virtual bool CancelInitiallySupported { get { return true; } } public virtual bool SingleInstanceTask { get { return true; } } public virtual bool LogExceptionsOnly { get { return false; } } public abstract string TaskName { get; } protected abstract void ExecuteTask(); #region Protected Triggers /// /// Schedules the Task to Begin Immediately /// protected ScheduledTaskStatus ScheduleTask() { return ScheduleTask(null, null); } /// /// Schedules the Task to Begin Immediately /// /// DataMap passed into the executing Task /// protected ScheduledTaskStatus ScheduleTask(JobDataMap DataMap) { return ScheduleTask(null, DataMap); } /// /// Schedules the Task to Begin based on the Trigger /// /// Trigger for the Task protected ScheduledTaskStatus ScheduleTask(TriggerBuilder Trigger) { return ScheduleTask(Trigger, null); } /// /// Schedules the Task to Begin based on the Trigger including the DataMap /// /// Trigger for the Task /// DataMap passed into the executing Task /// protected ScheduledTaskStatus ScheduleTask(TriggerBuilder Trigger, JobDataMap DataMap) { if (Trigger == null) Trigger = TriggerBuilder.Create(); // Defaults to Start Immediately if (DataMap != null) Trigger = Trigger.UsingJobData(DataMap); return ScheduledTasks.RegisterTask(this, Trigger); } #endregion public void Execute(IJobExecutionContext context) { // Task Status this.ExecutionContext = context; this.Status = context.GetDiscoScheduledTaskStatus(); if (this.Status == null) this.Status = ScheduledTasks.RegisterTask(this); try { if (!this.LogExceptionsOnly) ScheduledTasksLog.LogScheduledTaskExecuted(this.Status.TaskName, this.Status.SessionId); this.Status.Started(); this.ExecuteTask(); } catch (Exception ex) { ScheduledTasksLog.LogScheduledTaskException(this.Status.TaskName, this.Status.SessionId, this.GetType(), ex); this.Status.SetTaskException(ex); } finally { if (!this.Status.FinishedTimestamp.HasValue) // Scheduled Task Didn't Trigger 'Finished' this.Status.Finished(); this.Status.Finally(); var nextTriggerTime = context.NextFireTimeUtc; if (nextTriggerTime.HasValue) { // Continuous Task this.Status.Reset(nextTriggerTime.Value.LocalDateTime); } else { this.UnregisterTask(); } if (!this.LogExceptionsOnly) ScheduledTasksLog.LogScheduledTaskFinished(this.Status.TaskName, this.Status.SessionId); } } } }