public ActionResult Edit(ScheduleTaskModel model, bool continueEditing, string returnUrl = null) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageScheduleTasks)) { return(AccessDeniedView()); } ViewBag.ReturnUrl = returnUrl; if (!ModelState.IsValid) { return(View(model)); } var reloadResult = RedirectToAction("Edit", new { id = model.Id, returnUrl = returnUrl }); var returnResult = RedirectToReferrer(returnUrl, () => RedirectToAction("List")); var scheduleTask = _scheduleTaskService.GetTaskById(model.Id); if (scheduleTask == null) { NotifyError("Schedule task cannot be loaded"); return(reloadResult); } scheduleTask.Name = model.Name; scheduleTask.Enabled = model.Enabled; scheduleTask.StopOnError = model.StopOnError; scheduleTask.CronExpression = model.CronExpression; if (model.Enabled) { scheduleTask.NextRunUtc = _scheduleTaskService.GetNextSchedule(scheduleTask); } else { scheduleTask.NextRunUtc = null; } _scheduleTaskService.UpdateTask(scheduleTask); NotifySuccess(T("Admin.System.ScheduleTasks.UpdateSuccess")); if (continueEditing) { return(reloadResult); } return(returnResult); }
public ActionResult Edit(ScheduleTaskModel model, bool continueEditing, string returnUrl = null) { ViewBag.ReturnUrl = returnUrl; if (!ModelState.IsValid) { return(View(model)); } var scheduleTask = _scheduleTaskService.GetTaskById(model.Id); if (scheduleTask == null) { NotifyError("Schedule task cannot be loaded"); return(RedirectToAction("Edit", new { id = model.Id, returnUrl })); } scheduleTask.Name = model.Name; scheduleTask.Enabled = model.Enabled; scheduleTask.StopOnError = model.StopOnError; scheduleTask.CronExpression = model.CronExpression; scheduleTask.Priority = model.Priority; scheduleTask.NextRunUtc = model.Enabled ? _scheduleTaskService.GetNextSchedule(scheduleTask) : null; _scheduleTaskService.UpdateTask(scheduleTask); NotifySuccess(T("Admin.System.ScheduleTasks.UpdateSuccess")); if (continueEditing) { return(RedirectToAction("Edit", new { id = model.Id, returnUrl })); } else if (returnUrl.HasValue()) { return(RedirectToReferrer(returnUrl, () => RedirectToAction("List"))); } return(RedirectToAction("List")); }
public void Execute( ScheduleTask task, IDictionary <string, string> taskParameters = null, bool throwOnError = false) { if (task.IsRunning) { return; } if (AsyncRunner.AppShutdownCancellationToken.IsCancellationRequested) { return; } bool faulted = false; bool canceled = false; string lastError = null; ITask instance = null; string stateName = null; Type taskType = null; try { taskType = Type.GetType(task.Type); Debug.WriteLineIf(taskType == null, "Invalid task type: " + task.Type.NaIfEmpty()); if (taskType == null) { return; } if (!PluginManager.IsActivePluginAssembly(taskType.Assembly)) { return; } } catch { return; } try { Customer customer = null; // try virtualize current customer (which is necessary when user manually executes a task) if (taskParameters != null && taskParameters.ContainsKey(CurrentCustomerIdParamName)) { customer = _customerService.GetCustomerById(taskParameters[CurrentCustomerIdParamName].ToInt()); } if (customer == null) { // no virtualization: set background task system customer as current customer customer = _customerService.GetCustomerBySystemName(SystemCustomerNames.BackgroundTask); } _workContext.CurrentCustomer = customer; // create task instance instance = _taskResolver(taskType); stateName = task.Id.ToString(); // prepare and save entity task.LastStartUtc = DateTime.UtcNow; task.LastEndUtc = null; task.NextRunUtc = null; task.ProgressPercent = null; task.ProgressMessage = null; _scheduledTaskService.UpdateTask(task); // create & set a composite CancellationTokenSource which also contains the global app shoutdown token var cts = CancellationTokenSource.CreateLinkedTokenSource(AsyncRunner.AppShutdownCancellationToken, new CancellationTokenSource().Token); AsyncState.Current.SetCancelTokenSource <ScheduleTask>(cts, stateName); var ctx = new TaskExecutionContext(_componentContext, task) { ScheduleTask = task.Clone(), CancellationToken = cts.Token, Parameters = taskParameters ?? new Dictionary <string, string>() }; instance.Execute(ctx); } catch (Exception ex) { faulted = true; canceled = ex is OperationCanceledException; Logger.Error(string.Format("Error while running scheduled task '{0}'. {1}", task.Name, ex.Message), ex); lastError = ex.Message.Truncate(995, "..."); if (throwOnError) { throw; } } finally { // remove from AsyncState if (stateName.HasValue()) { AsyncState.Current.Remove <ScheduleTask>(stateName); } task.ProgressPercent = null; task.ProgressMessage = null; var now = DateTime.UtcNow; task.LastError = lastError; task.LastEndUtc = now; if (faulted) { if ((!canceled && task.StopOnError) || instance == null) { task.Enabled = false; } } else { task.LastSuccessUtc = now; } if (task.Enabled) { task.NextRunUtc = _scheduledTaskService.GetNextSchedule(task); } _scheduledTaskService.UpdateTask(task); } }
public void Execute( ScheduleTask task, IDictionary <string, string> taskParameters = null, bool throwOnError = false) { if (AsyncRunner.AppShutdownCancellationToken.IsCancellationRequested) { return; } if (task.LastHistoryEntry == null) { // The task was started manually. task.LastHistoryEntry = _scheduledTaskService.GetLastHistoryEntryByTaskId(task.Id); } if (task?.LastHistoryEntry?.IsRunning == true) { return; } bool faulted = false; bool canceled = false; string lastError = null; ITask instance = null; string stateName = null; Type taskType = null; Exception exception = null; var historyEntry = new ScheduleTaskHistory { ScheduleTaskId = task.Id, IsRunning = true, MachineName = _env.MachineName, StartedOnUtc = DateTime.UtcNow }; try { taskType = Type.GetType(task.Type); if (taskType == null) { Logger.DebugFormat("Invalid scheduled task type: {0}", task.Type.NaIfEmpty()); } if (taskType == null) { return; } if (!PluginManager.IsActivePluginAssembly(taskType.Assembly)) { return; } task.ScheduleTaskHistory.Add(historyEntry); _scheduledTaskService.UpdateTask(task); } catch { return; } try { // Task history entry has been successfully added, now we execute the task. // Create task instance. instance = _taskResolver(taskType); stateName = task.Id.ToString(); // Create & set a composite CancellationTokenSource which also contains the global app shoutdown token. var cts = CancellationTokenSource.CreateLinkedTokenSource(AsyncRunner.AppShutdownCancellationToken, new CancellationTokenSource().Token); _asyncState.SetCancelTokenSource <ScheduleTask>(cts, stateName); var ctx = new TaskExecutionContext(_componentContext, historyEntry) { ScheduleTaskHistory = historyEntry.Clone(), CancellationToken = cts.Token, Parameters = taskParameters ?? new Dictionary <string, string>() }; Logger.DebugFormat("Executing scheduled task: {0}", task.Type); instance.Execute(ctx); } catch (Exception ex) { exception = ex; faulted = true; canceled = ex is OperationCanceledException; lastError = ex.Message.Truncate(995, "..."); if (canceled) { Logger.Warn(ex, T("Admin.System.ScheduleTasks.Cancellation", task.Name)); } else { Logger.Error(ex, string.Concat(T("Admin.System.ScheduleTasks.RunningError", task.Name), ": ", ex.Message)); } } finally { var now = DateTime.UtcNow; var updateTask = false; historyEntry.IsRunning = false; historyEntry.ProgressPercent = null; historyEntry.ProgressMessage = null; historyEntry.Error = lastError; historyEntry.FinishedOnUtc = now; if (faulted) { if ((!canceled && task.StopOnError) || instance == null) { task.Enabled = false; updateTask = true; } } else { historyEntry.SucceededOnUtc = now; } try { Logger.DebugFormat("Executed scheduled task: {0}. Elapsed: {1} ms.", task.Type, (now - historyEntry.StartedOnUtc).TotalMilliseconds); // Remove from AsyncState. if (stateName.HasValue()) { _asyncState.Remove <ScheduleTask>(stateName); } } catch (Exception ex) { Logger.Error(ex); } if (task.Enabled) { task.NextRunUtc = _scheduledTaskService.GetNextSchedule(task); updateTask = true; } _scheduledTaskService.UpdateHistoryEntry(historyEntry); if (updateTask) { _scheduledTaskService.UpdateTask(task); } Throttle.Check("Delete old schedule task history entries", TimeSpan.FromDays(1), () => _scheduledTaskService.DeleteHistoryEntries() > 0); } if (throwOnError && exception != null) { throw exception; } }
public void Execute( ScheduleTask task, IDictionary <string, string> taskParameters = null, bool throwOnError = false) { if (task.IsRunning) { return; } if (AsyncRunner.AppShutdownCancellationToken.IsCancellationRequested) { return; } bool faulted = false; bool canceled = false; string lastError = null; ITask instance = null; string stateName = null; Type taskType = null; try { taskType = Type.GetType(task.Type); if (taskType == null) { Logger.DebugFormat("Invalid scheduled task type: {0}", task.Type.NaIfEmpty()); } if (taskType == null) { return; } if (!PluginManager.IsActivePluginAssembly(taskType.Assembly)) { return; } } catch { return; } try { // create task instance instance = _taskResolver(taskType); stateName = task.Id.ToString(); // prepare and save entity task.LastStartUtc = DateTime.UtcNow; task.LastEndUtc = null; task.NextRunUtc = null; task.ProgressPercent = null; task.ProgressMessage = null; _scheduledTaskService.UpdateTask(task); // create & set a composite CancellationTokenSource which also contains the global app shoutdown token var cts = CancellationTokenSource.CreateLinkedTokenSource(AsyncRunner.AppShutdownCancellationToken, new CancellationTokenSource().Token); _asyncState.SetCancelTokenSource <ScheduleTask>(cts, stateName); var ctx = new TaskExecutionContext(_componentContext, task) { ScheduleTask = task.Clone(), CancellationToken = cts.Token, Parameters = taskParameters ?? new Dictionary <string, string>() }; Logger.DebugFormat("Executing scheduled task: {0}", task.Type); instance.Execute(ctx); } catch (Exception exception) { faulted = true; canceled = exception is OperationCanceledException; lastError = exception.Message.Truncate(995, "..."); if (canceled) { Logger.Warn(exception, T("Admin.System.ScheduleTasks.Cancellation", task.Name)); } else { Logger.Error(exception, string.Concat(T("Admin.System.ScheduleTasks.RunningError", task.Name), ": ", exception.Message)); } if (throwOnError) { throw; } } finally { task.ProgressPercent = null; task.ProgressMessage = null; var now = DateTime.UtcNow; task.LastError = lastError; task.LastEndUtc = now; if (faulted) { if ((!canceled && task.StopOnError) || instance == null) { task.Enabled = false; } } else { task.LastSuccessUtc = now; } Logger.DebugFormat("Executed scheduled task: {0}. Elapsed: {1} ms.", task.Type, (now - task.LastStartUtc.Value).TotalMilliseconds); if (task.Enabled) { task.NextRunUtc = _scheduledTaskService.GetNextSchedule(task); } // remove from AsyncState if (stateName.HasValue()) { _asyncState.Remove <ScheduleTask>(stateName); } _scheduledTaskService.UpdateTask(task); } }