Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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"));
        }
Exemplo n.º 3
0
        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);
            }
        }
Exemplo n.º 4
0
        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;
            }
        }
Exemplo n.º 5
0
        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);
            }
        }