public void Can_save_and_load_scheduleTask()
        {
            var scheduleTask = new ScheduleTask
                               {
                                   Name = "Task 1",
                                   Seconds = 1,
                                   Type = "some type 1",
                                   Enabled = true,
                                   StopOnError = true,
                                   LastStartUtc = new DateTime(2010, 01, 01),
                                   LastEndUtc = new DateTime(2010, 01, 02),
                                   LastSuccessUtc= new DateTime(2010, 01, 03),
                               };

            var fromDb = SaveAndLoadEntity(scheduleTask);
            fromDb.ShouldNotBeNull();
            fromDb.Name.ShouldEqual("Task 1");
            fromDb.Seconds.ShouldEqual(1);
            fromDb.Type.ShouldEqual("some type 1");
            fromDb.Enabled.ShouldEqual(true);
            fromDb.StopOnError.ShouldEqual(true);
            fromDb.LastStartUtc.ShouldEqual(new DateTime(2010, 01, 01));
            fromDb.LastEndUtc.ShouldEqual(new DateTime(2010, 01, 02));
            fromDb.LastSuccessUtc.ShouldEqual(new DateTime(2010, 01, 03));
        }
コード例 #2
0
        protected ScheduleTaskModel PrepareScheduleTaskModel(ScheduleTask task)
        {
            var model = new ScheduleTaskModel()
            {
                Id = task.Id,
                Name = task.Name,
                Seconds = task.Seconds,
                Enabled = task.Enabled,
                StopOnError = task.StopOnError,
                LastStartUtc = task.LastStartUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastStartUtc.Value, DateTimeKind.Utc).ToString("G") : "",
                LastEndUtc = task.LastEndUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastEndUtc.Value, DateTimeKind.Utc).ToString("G") : "",
                LastSuccessUtc = task.LastSuccessUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastSuccessUtc.Value, DateTimeKind.Utc).ToString("G") : "",
				LastError = task.LastError.EmptyNull(),
				IsRunning =	task.IsRunning,		//task.LastStartUtc.GetValueOrDefault() > task.LastEndUtc.GetValueOrDefault(),
				Duration = ""
            };

			var span = TimeSpan.Zero;
			if (task.LastStartUtc.HasValue)
			{
				span = model.IsRunning ? DateTime.UtcNow - task.LastStartUtc.Value : task.LastEndUtc.Value - task.LastStartUtc.Value;
				model.Duration = span.ToString("g");
			}

            return model;
        }
コード例 #3
0
ファイル: Task.cs プロジェクト: GloriousOnion/SmartStoreNET
 /// <summary>
 /// Ctor for Task
 /// </summary>
 /// <param name="task">Task </param>
 public Task(ScheduleTask task)
 {
     this.Type = task.Type;
     this.Enabled = task.Enabled;
     this.StopOnError = task.StopOnError;
     this.Name = task.Name;
 }
コード例 #4
0
        /// <summary>
        /// Deletes a task
        /// </summary>
        /// <param name="task">Task</param>
        public virtual void DeleteTask(ScheduleTask task)
        {
            if (task == null)
                throw new ArgumentNullException("task");

            _taskRepository.Delete(task);
        }
コード例 #5
0
		private bool IsTaskInstalled(ScheduleTask task)
		{
			var type = Type.GetType(task.Type);
			if (type != null)
			{
				return PluginManager.IsActivePluginAssembly(type.Assembly);
			}
			return false;
		}
コード例 #6
0
        /// <summary>
        /// Ctor for Task
        /// </summary>
        /// <param name="task">Task </param>
        public Job(ScheduleTask task)
        {
			this.Type = task.Type;
            this.Enabled = task.Enabled;
            this.StopOnError = task.StopOnError;
            this.Name = task.Name;
			this.LastError = task.LastError;
			this.IsRunning = task.IsRunning;		//task.LastStartUtc.GetValueOrDefault() > task.LastEndUtc.GetValueOrDefault();
        }
コード例 #7
0
 protected ScheduleTaskModel PrepareScheduleTaskModel(ScheduleTask task)
 {
     var model = new ScheduleTaskModel()
     {
         Id = task.Id,
         Name = task.Name,
         Seconds = task.Seconds,
         Enabled = task.Enabled,
         StopOnError = task.StopOnError,
         LastStartUtc = task.LastStartUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastStartUtc.Value, DateTimeKind.Utc).ToString("G") : "",
         LastEndUtc = task.LastEndUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastEndUtc.Value, DateTimeKind.Utc).ToString("G") : "",
         LastSuccessUtc = task.LastSuccessUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastSuccessUtc.Value, DateTimeKind.Utc).ToString("G") : "",
     };
     return model;
 }
コード例 #8
0
        public virtual void UpdateTask(ScheduleTask task)
        {
            if (task == null)
                throw new ArgumentNullException("task");

            bool saveFailed;
            bool? autoCommit = null;

            do
            {
                saveFailed = false;

                // ALWAYS save immediately
                try
                {
                    autoCommit = _taskRepository.AutoCommitEnabled;
                    _taskRepository.AutoCommitEnabled = true;
                    _taskRepository.Update(task);
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    saveFailed = true;

                    var entry = ex.Entries.Single();
                    var current = (ScheduleTask)entry.CurrentValues.ToObject(); // from current scope

                    // When 'StopOnError' is true, the 'Enabled' property could have been be set to true on exception.
                    var enabledModified = entry.Property("Enabled").IsModified;

                    // Save current cron expression
                    var cronExpression = task.CronExpression;

                    // Fetch Name, CronExpression, Enabled & StopOnError from database
                    // (these were possibly edited thru the backend)
                    _taskRepository.Context.ReloadEntity(task);

                    // Do we have to reschedule the task?
                    var cronModified = cronExpression != task.CronExpression;

                    // Copy execution specific data from current to reloaded entity
                    task.LastEndUtc = current.LastEndUtc;
                    task.LastError = current.LastError;
                    task.LastStartUtc = current.LastStartUtc;
                    task.LastSuccessUtc = current.LastSuccessUtc;
                    task.ProgressMessage = current.ProgressMessage;
                    task.ProgressPercent = current.ProgressPercent;
                    task.NextRunUtc = current.NextRunUtc;
                    if (enabledModified)
                    {
                        task.Enabled = current.Enabled;
                    }
                    if (task.NextRunUtc.HasValue && cronModified)
                    {
                        // reschedule task
                        task.NextRunUtc = GetNextSchedule(task);
                    }
                }
                finally
                {
                    _taskRepository.AutoCommitEnabled = autoCommit;
                }
            } while (saveFailed);
        }
コード例 #9
0
 internal TaskThread(ScheduleTask scheduleTask)
 {
     this._jobs = new Dictionary<string, Job>();
     this._seconds = scheduleTask.Seconds;
     this._isRunning = false;
 }
コード例 #10
0
		public virtual void SetupModel(FeedFroogleModel model, ScheduleTask task = null)
		{
			var stores = _storeService.GetAllStores().ToList();

			model.AvailableCurrencies = Helper.AvailableCurrencies();
			model.AvailableGoogleCategories = GetTaxonomyList();
			model.GeneratedFiles = Helper.FeedFiles(stores);
			model.Helper = Helper;

			model.AvailableStores = new List<SelectListItem>();
			model.AvailableStores.Add(new SelectListItem() { Text = Helper.Resource("Admin.Common.All"), Value = "0" });
			model.AvailableStores.AddRange(_storeService.GetAllStores().ToSelectListItems());

			if (task != null)
			{
				model.GenerateStaticFileEachMinutes = task.Seconds / 60;
				model.TaskEnabled = task.Enabled;
			}
		}
コード例 #11
0
        private bool IsTaskVisible(ScheduleTask task)
        {
            if (task.IsHidden)
                return false;

            var type = Type.GetType(task.Type);
            if (type != null)
            {
                return PluginManager.IsActivePluginAssembly(type.Assembly);
            }
            return false;
        }
コード例 #12
0
        public virtual ExportProfile InsertExportProfile(
			string providerSystemName,
			string name,
			string fileExtension,
			ExportFeatures features,
			bool isSystemProfile = false,
			string profileSystemName = null,
			int cloneFromProfileId = 0)
        {
            Guard.ArgumentNotEmpty(() => providerSystemName);

            var profileCount = _exportProfileRepository.Table.Count(x => x.ProviderSystemName == providerSystemName);

            if (name.IsEmpty())
                name = providerSystemName;

            if (!isSystemProfile)
                name = string.Concat(_localizationService.GetResource("Common.My"), " ", name);

            name = string.Concat(name, " ", profileCount + 1);

            var cloneProfile = GetExportProfileById(cloneFromProfileId);

            ScheduleTask task = null;
            ExportProfile profile = null;

            if (cloneProfile == null)
            {
                task = new ScheduleTask
                {
                    CronExpression = "0 */6 * * *",     // every six hours
                    Type = typeof(DataExportTask).AssemblyQualifiedNameWithoutVersion(),
                    Enabled = false,
                    StopOnError = false,
                    IsHidden = true
                };
            }
            else
            {
                task = cloneProfile.ScheduleTask.Clone();
                task.LastEndUtc = task.LastStartUtc = task.LastSuccessUtc = null;
            }

            task.Name = string.Concat(name, " Task");

            _scheduleTaskService.InsertTask(task);

            if (cloneProfile == null)
            {
                profile = new ExportProfile
                {
                    FileNamePattern = _defaultFileNamePattern
                };

                if (isSystemProfile)
                {
                    profile.Enabled = true;
                    profile.PerStore = false;
                    profile.CreateZipArchive = false;
                    profile.Cleanup = false;
                }
                else
                {
                    // what we do here is to preset typical settings for feed creation
                    // but on the other hand they may be untypical for generic data export\exchange
                    var projection = new ExportProjection
                    {
                        RemoveCriticalCharacters = true,
                        CriticalCharacters = "¼,½,¾",
                        PriceType = PriceDisplayType.PreSelectedPrice,
                        NoGroupedProducts = (features.HasFlag(ExportFeatures.CanOmitGroupedProducts) ? true : false),
                        DescriptionMerging = ExportDescriptionMerging.Description
                    };

                    var filter = new ExportFilter
                    {
                        IsPublished = true
                    };

                    profile.Projection = XmlHelper.Serialize<ExportProjection>(projection);
                    profile.Filtering = XmlHelper.Serialize<ExportFilter>(filter);
                }
            }
            else
            {
                profile = cloneProfile.Clone();
            }

            profile.IsSystemProfile = isSystemProfile;
            profile.Name = name;
            profile.ProviderSystemName = providerSystemName;
            profile.SchedulingTaskId = task.Id;

            var cleanedSystemName = providerSystemName
                .Replace("Exports.", "")
                .Replace("Feeds.", "")
                .Replace("/", "")
                .Replace("-", "");

            var folderName = SeoHelper.GetSeName(cleanedSystemName, true, false)
                .ToValidPath()
                .Truncate(_dataExchangeSettings.MaxFileNameLength);

            profile.FolderName = "~/App_Data/ExportProfiles/" + FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/App_Data/ExportProfiles"), folderName);

            if (profileSystemName.IsEmpty() && isSystemProfile)
                profile.SystemName = cleanedSystemName;
            else
                profile.SystemName = profileSystemName;

            _exportProfileRepository.Insert(profile);

            task.Alias = profile.Id.ToString();
            _scheduleTaskService.UpdateTask(task);

            if (fileExtension.HasValue() && !isSystemProfile)
            {
                if (cloneProfile == null)
                {
                    if (features.HasFlag(ExportFeatures.CreatesInitialPublicDeployment))
                    {
                        var subFolder = FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/" + DataExporter.PublicFolder), folderName);

                        profile.Deployments.Add(new ExportDeployment
                        {
                            ProfileId = profile.Id,
                            Enabled = true,
                            DeploymentType = ExportDeploymentType.PublicFolder,
                            Name = profile.Name,
                            SubFolder = subFolder
                        });

                        UpdateExportProfile(profile);
                    }
                }
                else
                {
                    foreach (var deployment in cloneProfile.Deployments)
                    {
                        profile.Deployments.Add(deployment.Clone());
                    }

                    UpdateExportProfile(profile);
                }
            }

            _eventPublisher.EntityInserted(profile);

            return profile;
        }
コード例 #13
0
        protected ScheduleTaskModel PrepareScheduleTaskModel(ScheduleTask task)
        {
            var now = DateTime.UtcNow;

            TimeSpan? dueIn = null;
            if (task.NextRunUtc.HasValue)
            {
                dueIn = task.NextRunUtc.Value - now;
            }

            var nextRunPretty = "";
            bool isOverdue = false;
            if (dueIn.HasValue)
            {
                if (dueIn.Value.TotalSeconds > 0)
                {
                    nextRunPretty = dueIn.Value.Prettify();
                }
                else
                {
                    nextRunPretty = T("Common.Waiting") + "...";
                    isOverdue = true;
                }
            }

            var isRunning = task.IsRunning;
            var lastStartOn = task.LastStartUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastStartUtc.Value, DateTimeKind.Utc) : (DateTime?)null;
            var lastEndOn = task.LastEndUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastEndUtc.Value, DateTimeKind.Utc) : (DateTime?)null;
            var lastSuccessOn = task.LastSuccessUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.LastSuccessUtc.Value, DateTimeKind.Utc) : (DateTime?)null;
            var nextRunOn = task.NextRunUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(task.NextRunUtc.Value, DateTimeKind.Utc) : (DateTime?)null;

            var model = new ScheduleTaskModel
            {
                Id = task.Id,
                Name = task.Name,
                CronExpression = task.CronExpression,
                CronDescription = CronExpression.GetFriendlyDescription(task.CronExpression),
                Enabled = task.Enabled,
                StopOnError = task.StopOnError,
                LastStart = lastStartOn,
                LastStartPretty = task.LastStartUtc.HasValue ? task.LastStartUtc.Value.RelativeFormat(true, "f") : "",
                LastEnd = lastEndOn,
                LastEndPretty = lastEndOn.HasValue ? lastEndOn.Value.ToString("G") : "",
                LastSuccess = lastSuccessOn,
                LastSuccessPretty = lastSuccessOn.HasValue ? lastSuccessOn.Value.ToString("G") : "",
                NextRun = nextRunOn,
                NextRunPretty = nextRunPretty,
                LastError = task.LastError.EmptyNull(),
                IsRunning = isRunning,
                CancelUrl = Url.Action("CancelJob", new { id = task.Id }),
                ExecuteUrl = Url.Action("RunJob", new { id = task.Id }),
                EditUrl = Url.Action("Edit", new { id = task.Id }),
                ProgressPercent = task.ProgressPercent,
                ProgressMessage = task.ProgressMessage,
                IsOverdue = isOverdue,
                Duration = ""
            };

            var span = TimeSpan.Zero;
            if (task.LastStartUtc.HasValue)
            {
                span = model.IsRunning ? now - task.LastStartUtc.Value : task.LastEndUtc.Value - task.LastStartUtc.Value;
                if (span > TimeSpan.Zero)
                {
                    model.Duration = span.ToString("g");
                }
            }

            return model;
        }
コード例 #14
0
        public virtual ImportProfile InsertImportProfile(string fileName, string name, ImportEntityType entityType)
        {
            Guard.ArgumentNotEmpty(() => fileName);

            if (name.IsEmpty())
                name = GetNewProfileName(entityType);

            var task = new ScheduleTask
            {
                CronExpression = "0 */24 * * *",
                Type = typeof(DataImportTask).AssemblyQualifiedNameWithoutVersion(),
                Enabled = false,
                StopOnError = false,
                IsHidden = true
            };

            task.Name = string.Concat(name, " Task");

            _scheduleTaskService.InsertTask(task);

            var profile = new ImportProfile
            {
                Name = name,
                EntityType = entityType,
                Enabled = true,
                SchedulingTaskId = task.Id
            };

            if (Path.GetExtension(fileName).IsCaseInsensitiveEqual(".xlsx"))
                profile.FileType = ImportFileType.XLSX;
            else
                profile.FileType = ImportFileType.CSV;

            string[] keyFieldNames = null;

            switch (entityType)
            {
                case ImportEntityType.Product:
                    keyFieldNames = ProductImporter.DefaultKeyFields;
                    break;
                case ImportEntityType.Category:
                    keyFieldNames = CategoryImporter.DefaultKeyFields;
                    break;
                case ImportEntityType.Customer:
                    keyFieldNames = CustomerImporter.DefaultKeyFields;
                    break;
                case ImportEntityType.NewsLetterSubscription:
                    keyFieldNames = NewsLetterSubscriptionImporter.DefaultKeyFields;
                    break;
            }

            profile.KeyFieldNames = string.Join(",", keyFieldNames);

            profile.FolderName = SeoHelper.GetSeName(name, true, false)
                .ToValidPath()
                .Truncate(_dataExchangeSettings.MaxFileNameLength);

            profile.FolderName = FileSystemHelper.CreateNonExistingDirectoryName(CommonHelper.MapPath("~/App_Data/ImportProfiles"), profile.FolderName);

            _importProfileRepository.Insert(profile);

            task.Alias = profile.Id.ToString();
            _scheduleTaskService.UpdateTask(task);

            _eventPublisher.EntityInserted(profile);

            return profile;
        }
コード例 #15
0
        public virtual DateTime? GetNextSchedule(ScheduleTask task)
        {
            if (task.Enabled)
            {
                try
                {
                    var baseTime = _dateTimeHelper.ConvertToUserTime(DateTime.UtcNow);
                    var next = CronExpression.GetNextSchedule(task.CronExpression, baseTime);
                    return _dateTimeHelper.ConvertToUtcTime(next);
                }
                catch { }
            }

            return null;
        }
コード例 #16
0
ファイル: TaskExecutor.cs プロジェクト: mandocaesar/Mesinku
        public void Execute(ScheduleTask task, 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 (!PluginManager.IsActivePluginAssembly(taskType.Assembly))
                    return;
            }
            catch
            {
                return;
            }

            try
            {
                // set background task system customer as current customer
                var 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
                };

                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);
            }
        }
コード例 #17
0
        private string GetTaskMessage(ScheduleTask task, string resourceKey)
        {
            string message = null;

            var taskClassName = task.Type
                .SplitSafe(",")
                .SafeGet(0)
                .SplitSafe(".")
                .LastOrDefault();

            if (taskClassName.HasValue())
            {
                message = _localizationService.GetResource(string.Concat(resourceKey, ".", taskClassName), returnEmptyIfNotFound: true);
            }

            if (message.IsEmpty())
            {
                message = T(resourceKey);
            }

            return message;
        }