Exemple #1
0
        public ActionResult Finalize(bool restart)
        {
            _asyncState.Remove <InstallationResult>();

            if (restart)
            {
                var webHelper = EngineContext.Current.Resolve <IWebHelper>();
                webHelper.RestartAppDomain();
            }

            return(Json(new { Success = true }));
        }
Exemple #2
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
            {
                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.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
            {
                // remove from AsyncState
                if (stateName.HasValue())
                {
                    _asyncState.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;
                }

                Logger.DebugFormat("Executed scheduled task: {0}. Elapsed: {1} ms.", task.Type, (now - task.LastStartUtc.Value).TotalMilliseconds);

                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 Import(ProductImportModel model)
        {
            var controllingData = ConnectionCache.ControllingData();

            if (!controllingData.IsImportEnabled)
            {
                _services.Notifier.Error(T("Plugins.SmartStore.ShopConnector.ImportNotActive"));
                return;
            }

            if (_asyncState.Exists <ShopConnectorProcessingInfo>(ShopConnectorPlugin.SystemName))
            {
                _asyncState.Remove <ShopConnectorProcessingInfo>(ShopConnectorPlugin.SystemName);
            }

            var utcNow = DateTime.UtcNow;
            var state  = new ShopConnectorImportState
            {
                ImportCategories         = model.ImportCategories,
                ImportAll                = model.ImportAll,
                ImportFile               = model.ImportFile,
                UpdateExistingProducts   = model.UpdateExistingProducts,
                UpdateExistingCategories = model.UpdateExistingCategories,
                DeleteImportFile         = model.DeleteImportFile,
                TaxCategoryId            = model.TaxCategoryId,
                LimitedToStores          = model.LimitedToStores,
                EventPublishEntityCount  = 100,
                Publish               = model.Publish,
                DisableBuyButton      = model.DisableBuyButton,
                DisableWishlistButton = model.DisableWishlistButton
            };

            try
            {
                state.IgnoreEntityNames = _shopConnectorSettings.IgnoreEntityNames
                                          .SplitSafe(",")
                                          .Select(x => x.TrimSafe())
                                          .ToList();

                if (model.SelectedStoreIds != null && model.SelectedStoreIds.Any())
                {
                    state.SelectedStoreIds = model.SelectedStoreIds.ToList();
                }

                if (!model.ImportAll && !string.IsNullOrWhiteSpace(model.SelectedProductIds))
                {
                    state.SelectedProductIds = model.SelectedProductIds.SplitSafe(",").Select(x => x.ToInt()).ToDictionarySafe(x => x, x => 0);
                }

                var task = AsyncRunner.Run((c, ct, x) =>
                {
                    var obj = x as ShopConnectorImportState;
                    c.Resolve <IShopConnectorImportService>().StartProductImport(obj);
                }, state);

                _services.Notifier.Information(new LocalizedString(T("Plugins.SmartStore.ShopConnector.ImportInProgress")));

                task.Wait(500);
            }
            catch (Exception ex)
            {
                _services.Notifier.Error(ex.ToAllMessages());
                Logger.Error(ex);
            }
        }