protected void TasksScheduledThread() { while (true) { log.TraceFormat("{0:S} - Check for tasks to schedule", this.ToString()); try { using (SqlConnection conn = new SqlConnection(ConnectionString)) { conn.Open(); using (SqlTransaction trans = conn.BeginTransaction(System.Data.IsolationLevel.Serializable)) { // Get enabled schedules var lSchedules = Schedule.GetAndLockEnabledNotRunning(conn, trans); #region look for schedules to fire lSchedules.ForEach(sched => { NCrontab.CrontabSchedule cs = NCrontab.CrontabSchedule.Parse(sched.Cron); if (cs.GetNextOccurrence(LastScheduleCheck) < DateTime.Now && (sched.LastFired < cs.GetNextOccurrence(LastScheduleCheck))) { var task = YoctoScheduler.Core.Database.Task.GetByID <Task>(conn, trans, sched.TaskID); log.InfoFormat("Starting schedulation {0:S} due to cron {1:S}", task.ToString(), sched.ToString()); // save schedule fire time sched.LastFired = DateTime.Now; Schedule.Update(conn, trans, sched); ExecutionQueueItem eqi = new ExecutionQueueItem() { TaskID = task.ID, Priority = Priority.Normal, ScheduleID = sched.ID, Inserted = DateTime.Now }; ExecutionQueueItem.Insert(conn, trans, eqi); log.InfoFormat("Execution enqueued {0:S}", eqi.ToString()); } }); #endregion trans.Commit(); } } LastScheduleCheck = DateTime.Now; Thread.Sleep(int.Parse(Configuration["SERVER_POLL_TASK_SCHEDULER_SLEEP_MS"])); } catch (Exception exce) // catch all to keep the thread alive { log.ErrorFormat("Unhandled exception during TasksScheduledThread: {0:S}", exce.ToString()); } } }
public void ExecutionQueueItem_InsertNull() { ExecutionQueueItem eqi = new ExecutionQueueItem() { Inserted = DateTime.Now, Priority = Core.Priority.Lowest, TaskID = 1 }; using (SqlConnection conn = new SqlConnection(Config.CONNECTION_STRING)) { conn.Open(); using (var trans = conn.BeginTransaction()) { ExecutionQueueItem.Insert(conn, trans, eqi); trans.Commit(); } } }
protected void DeadTasksThread() { while (true) { try { log.TraceFormat("{0:S} - Check for dead tasks", this.ToString()); // a task is dead if there is no update in the xxx milliseconds (1 minute default) int iTimeoutMilliseconds = int.Parse(Configuration["TASK_MAXIMUM_UPDATE_LAG_MS"]); using (SqlConnection conn = new SqlConnection(ConnectionString)) { conn.Open(); using (SqlTransaction trans = conn.BeginTransaction(System.Data.IsolationLevel.ReadCommitted)) { var lExpired = LiveExecutionStatus.GetAndLockExpired(conn, trans, iTimeoutMilliseconds); foreach (var les in lExpired) { #region Mark execution as expired // insert into dead table DeadExecutionStatus des = new DeadExecutionStatus(les, TaskStatus.Dead, null); DeadExecutionStatus.Insert(conn, trans, des); log.WarnFormat("Setting LiveExecutionStatus {0:S} as dead", les.ToString()); // remove from live table if (!LiveExecutionStatus.Delete(conn, trans, les)) { throw new Exceptions.DatabaseConcurrencyException <LiveExecutionStatus>("Delete", les); } // if required, reenqueue var task = YoctoScheduler.Core.Database.Task.GetByID <Task>(conn, trans, les.TaskID); if (task.ReenqueueOnDead) { log.InfoFormat("Reenqueuing {0:S} as requested", task.ToString()); ExecutionQueueItem eqi = new ExecutionQueueItem() { TaskID = task.ID, Priority = Priority.Normal, ScheduleID = les.ScheduleID, Inserted = DateTime.Now }; ExecutionQueueItem.Insert(conn, trans, eqi); } #endregion } trans.Commit(); } } Thread.Sleep(int.Parse(Configuration["SERVER_POLL_DISABLE_DEAD_TASKS_SLEEP_MS"])); } catch (Exception exce) // catch all to keep the thread alive { log.ErrorFormat("Unhandled exception during DeadTasksThread: {0:S}", exce.ToString()); } } }