/// <summary> /// Unschedule an existing task based on the view model /// </summary> /// <param name="vm">The view model corresponding to the task we want to unschedule</param> public void UnscheduleTask(ScheduledTaskViewModel vm) { //get the part ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.Get <ScheduledTaskPart>(vm.Id); int tId = part.RunningTaskId; if (tId > 0) { var str = _repoTasks.Get(tId); if (str != null) { _repoTasks.Delete(str); } else { //tId might have changed since the moment we got the information into the view models //e.g. if the task is periodic, it will generate a new Id and update it. //let's check here if there are tasks with the part id in the TaskType //(see the ScheduleTask method for the format we are using) var records = _repoTasks.Table.ToList().Where(rec => //rec.TaskType.Split(new string[]{"_"}, StringSplitOptions.RemoveEmptyEntries).Last().Equals(part.Id.ToString()) rec.TaskType.IndexOf(Constants.TaskTypeBase) == 0 ).ToList().Where(rec => rec.TaskType.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries).Last().Equals(part.Id.ToString()) ).ToList(); foreach (var item in records) { _repoTasks.Delete(item); } } } part.RunningTaskId = 0; }
public ScheduledTaskViewModel(ScheduledTaskPart part, IOrchardServices orchardServices, IDateLocalizationServices dateServices) : this(orchardServices, dateServices) { Id = part.Id; SignalName = part.SignalName; _scheduledStartUTC = part.ScheduledStartUTC == null ? (DateTime?)null : part.ScheduledStartUTC.Value.ToLocalTime(); PeriodicityTime = part.PeriodicityTime; PeriodicityUnit = part.PeriodicityUnit; ContentItemId = part.ContentItemId; Running = part.RunningTaskId; Delete = false; Autodestroy = part.Autodestroy; ExecutionType = part.ExecutionType; LongTask = part.LongTask; }
public ScheduledTaskViewModel(ScheduledTaskPart part) { Id = part.Id; SignalName = part.SignalName; ScheduledStartUTC = part.ScheduledStartUTC == null ? (DateTime?)null : part.ScheduledStartUTC.Value.ToLocalTime(); PeriodicityTime = part.PeriodicityTime; PeriodicityUnit = part.PeriodicityUnit; ContentItemId = part.ContentItemId; Running = part.RunningTaskId; Delete = false; Autodestroy = part.Autodestroy; ExecutionType = part.ExecutionType; LongTask = part.LongTask; }
/// <summary> /// Schedule a new task based on the information in the view model /// </summary> /// <param name="vm">The view model we are basing the new task on</param> public void ScheduleTask(ScheduledTaskViewModel vm) { //get the part ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.Get <ScheduledTaskPart>(vm.Id); //define tasktype: BASE_SIGNALNAME_ID string taskTypeStr = Constants.TaskTypeBase + "_" + part.SignalName + "_" + part.Id; ContentItem ci = null; if (part.ContentItemId > 0) { ci = _orchardServices.ContentManager.Get(part.ContentItemId); } _taskManager.CreateTask(taskTypeStr, part.ScheduledStartUTC ?? DateTime.UtcNow, ci); part.RunningTaskId = _repoTasks.Get(str => str.TaskType.Equals(taskTypeStr)).Id; }
public void UpdateRecordsAndSchedule(List <ScheduledTaskViewModel> vms) { foreach (ScheduledTaskViewModel vm in vms) { //if Id != 0 the task was already in the db if (vm.Id != 0) { //Should we try to delete? if (vm.Delete) { //if there is a corresponding task that is running, we should stop it first if (vm.Running > 0) { //stop the task with id == vm.Running UnscheduleTask(vm); } //the task is definitely not running, so we may safely remove the scheduler _orchardServices.ContentManager.Remove(_orchardServices.ContentManager.Get(vm.Id)); //(note that a handler is invoked to clean up the repositor) } else { //update the part ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.Get <ScheduledTaskPart>(vm.Id); vm.UpdatePart(part); } } else { //we have to create a new record if (!vm.Delete) { //we only create it if it was not also deleted already ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.New <ScheduledTaskPart>("ScheduledTask"); vm.UpdatePart(part); _orchardServices.ContentManager.Create(part); vm.Id = part.Id; string taskTypeStr = Constants.TaskTypeBase + "_" + part.SignalName + "_" + part.Id; if (vm.LinkedContent == null && part.ContentItemId > 0) { vm.LinkedContent = _orchardServices.ContentManager.Get(part.ContentItemId); } part.RunningTaskId = CreateTask(taskTypeStr, part.ScheduledStartUTC ?? DateTime.UtcNow, vm.LinkedContent); } } } }
/// <summary> /// computes the next DateTime for scheduling based off the information in the part /// </summary> /// <param name="part">The part containing the scheduling information</param> /// <returns>A <type>DateTime</type> object containing the moment when the task whoudl be scheduled next.</returns> public DateTime ComputeNextScheduledTime(ScheduledTaskPart part) { DateTime result = part.ScheduledStartUTC == null ? DateTime.UtcNow : part.ScheduledStartUTC.Value; // incrementa la start date in base alla periodicità fino a raggiungere una start date futura // la periodicità è sicuramente > 0 come verificato nell'handler, quindi il ciclo seguente non è infinito while (result <= DateTime.UtcNow) { switch (part.PeriodicityUnit) { case TimeUnits.Seconds: result = result.AddSeconds(part.PeriodicityTime); break; case TimeUnits.Minutes: result = result.AddMinutes(part.PeriodicityTime); break; case TimeUnits.Hours: result = result.AddHours(part.PeriodicityTime); break; case TimeUnits.Days: result = result.AddDays(part.PeriodicityTime); break; case TimeUnits.Weeks: result = result.AddDays(7 * part.PeriodicityTime); break; case TimeUnits.Months: result = result.AddMonths(part.PeriodicityTime); break; case TimeUnits.Years: result = result.AddYears(part.PeriodicityTime); break; default: break; } } part.ScheduledStartUTC = result; return(result); }
//public ScheduledTaskPart CreatePartFromVM() { // return new ScheduledTaskPart { // SignalName = this.SignalName, // ScheduledStartUTC = this.ScheduledStartUTC, // PeriodicityTime = this.PeriodicityTime, // PeriodicityUnit = this.PeriodicityUnit, // ContentItemId = this.ContentItemId, // RunningTaskId = this.Running // }; //} //public LaserTaskSchedulerRecord CreateRecordFromVM() { // LaserTaskSchedulerRecord ltsr = new LaserTaskSchedulerRecord(); // ltsr.SignalName = this.SignalName; // ltsr.ScheduledStartUTC = this.ScheduledStartUTC; // ltsr.PeriodicityTime = this.PeriodicityTime; // ltsr.PeriodicityUnit = this.PeriodicityUnit.ToString(); // ltsr.ContentItemId = this.ContentItemId; // ltsr.RunningTaskId = this.Running; // return ltsr; // //return new LaserTaskSchedulerRecord { // // SignalName = this.SignalName, // // ScheduledStartUTC = this.ScheduledStartUTC, // // PeriodicityTime = this.PeriodicityTime, // // PeriodicityUnit = this.PeriodicityUnit.ToString(), // // ContentItemId = this.ContentItemId, // // RunningTaskId = this.Running // //}; //} public void UpdatePart(ScheduledTaskPart part) { part.SignalName = this.SignalName; try { part.ScheduledStartUTC = _scheduledStartUTC == null ? (DateTime?)null : _scheduledStartUTC.Value.ToUniversalTime(); } catch (Exception) { //the date in the input was not valid part.ScheduledStartUTC = null; } part.PeriodicityTime = this.PeriodicityTime; part.PeriodicityUnit = this.PeriodicityUnit; part.ContentItemId = this.ContentItemId; part.RunningTaskId = this.Running; part.Autodestroy = this.Autodestroy; part.ExecutionType = this.ExecutionType; part.LongTask = this.LongTask; }
/// <summary> /// Updates the reords for the schedulers based on the changes from the UI /// </summary> /// <param name="vms">A list of view models that hold the updated information</param> public void UpdateRecords(List <ScheduledTaskViewModel> vms) { foreach (ScheduledTaskViewModel vm in vms) { //if Id != 0 the task was already in the db if (vm.Id != 0) { //Should we try to delete? if (vm.Delete) { //if there is a corresponding task that is running, we should stop it first if (vm.Running > 0) { //stop the task with id == vm.Running UnscheduleTask(vm); } //the task is definitely not running, so we may safely remove the scheduler _orchardServices.ContentManager.Remove(_orchardServices.ContentManager.Get(vm.Id)); //(note that a handler is invoked to clean up the repositor) } else { //update the part ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.Get <ScheduledTaskPart>(vm.Id); vm.UpdatePart(part); } } else { //we have to create a new record if (!vm.Delete) { //we only create it if it was not also deleted already ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.New <ScheduledTaskPart>("ScheduledTask"); vm.UpdatePart(part); _orchardServices.ContentManager.Create(part); vm.Id = part.Id; } } } }
public void Process(ScheduledTaskContext context) { string taskTypeStr = context.Task.TaskType; if (taskTypeStr.IndexOf(Constants.TaskTypeBase) == 0) { try { //For some reason, querying the db for the records related to the task returns null //Hence, we placed the part id in the TaskType. int pid = int.Parse(taskTypeStr.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries).Last()); ScheduledTaskPart part = (ScheduledTaskPart)_orchardServices.ContentManager.Get <ScheduledTaskPart>(pid); if (part == null) { Logger.Error("Laser.TaskScheduler was unable to identify and process the task of type " + taskTypeStr); } else { //Trigger the event //get the signal name for from the part to track edits that may have been done. if (part.ExecutionType == ExecutionTypes.WorkFlow) { _workflowManager.TriggerEvent( SignalActivity.SignalEventName, context.Task.ContentItem, () => new Dictionary <string, object> { { "Content", context.Task.ContentItem }, { SignalActivity.SignalEventName, part.SignalName } } ); } else { if (part.ExecutionType == ExecutionTypes.Razor) { if (part.LongTask) { _sweepGenerator.Terminate(); try { var result = _razorExecuteService.Execute(part.SignalName, context.Task.ContentItem, new Dictionary <string, object>() { { "Content", context.Task.ContentItem }, { SignalActivity.SignalEventName, part.SignalName } }).Trim(); } catch (Exception ex) { Logger.Error(ex, "ScheduledTaskTasksHandler -> Long Task Error on " + taskTypeStr + ex.Message); } finally { if (part.LongTask) { _sweepGenerator.Activate(); } } } else { var result = _razorExecuteService.Execute(part.SignalName, context.Task.ContentItem, new Dictionary <string, object>() { { "Content", context.Task.ContentItem }, { SignalActivity.SignalEventName, part.SignalName } }).Trim(); } } } if (part.Autodestroy) { var sc = new ScheduledTaskViewModel(part); sc.Delete = true; var list = new List <ScheduledTaskViewModel>(); list.Add(sc); _scheduledTaskService.UpdateRecords(list); } else { //if the part has periodicity and it was not unscheduled, we may reschedule the task if (part.PeriodicityTime > 0 && part.RunningTaskId > 0) { //define tasktype string newTaskTypeStr = Constants.TaskTypeBase + "_" + part.SignalName + "_" + part.Id; ContentItem ci = null; if (part.ContentItemId > 0) { ci = _orchardServices.ContentManager.Get(part.ContentItemId); } DateTime scheduleTime = _scheduledTaskService.ComputeNextScheduledTime(part); _taskManager.CreateTask(newTaskTypeStr, scheduleTime, ci); part.RunningTaskId = _repoTasks.Get(str => str.TaskType.Equals(newTaskTypeStr)).Id; } else { part.RunningTaskId = 0; } } } } catch (Exception ex) { Logger.Error(ex, "ScheduledTaskTasksHandler -> Error on " + taskTypeStr + " id= " + context.Task.ContentItem + ex.Message); } } }