Пример #1
0
        /// inheritedDoc
        public async Task EnqueueAllAsync()
        {
            try
            {
                var activeTriggers = await _triggerRepository.GetAll()
                                     .Where(t => t.Job.JobStatus == JobStatus.Active && t.Job.StartupMode == StartUpMode.Automatic && t.Status == TriggerStatus.Enabled)
                                     .ToListAsync();

                // remove all unused triggers
                var allRecurringJobs = JobStorage.Current.GetConnection().GetRecurringJobs();
                var jobsToRemove     = allRecurringJobs.Where(j => activeTriggers.All(t => t.Id.ToString() != j.Id)).ToList();

                foreach (var jobDto in jobsToRemove)
                {
                    RecurringJob.RemoveIfExists(jobDto.Id);
                }

                // update existing triggers
                foreach (var trigger in activeTriggers)
                {
                    if (!CronStringHelper.IsValidCronExpression(trigger.CronString))
                    {
                        Logger.Warn($"Trigger {trigger.Id} has has invalid CRON expression: {trigger.CronString} - skipped");
                        continue;
                    }

                    RecurringJob.AddOrUpdate <ScheduledJobAppService>(trigger.Id.ToString(), s => s.RunTriggerAsync(trigger.Id, CancellationToken.None), trigger.CronString);
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }
Пример #2
0
        public void CronPerInterval_GivenIntervalAndTime_ReturnsCorrectCronString(Scheduling schedule, int year, int month, int day, string expected)
        {
            var dateToTest = new DateTime(year, month, day);
            var result     = CronStringHelper.CronPerInterval(schedule, dateToTest);

            Assert.Equal(expected, result);
        }
 public void AddValidationErrors(CustomValidationContext context)
 {
     if (!string.IsNullOrWhiteSpace(CronString) && !CronStringHelper.IsValidCronExpression(CronString))
     {
         context.Results.Add(new ValidationResult("CRON String is invalid"));
     }
 }
Пример #4
0
        public void CreateFromAlarmDateAndScheduleReturns_With_Yearly_Interval_HandlesAlarmDate_InLeap_Year()
        {
            //Arrange
            var leapYearDate     = new DateTime(2020, 2, 29);
            var expectedInterval = CronStringHelper.CronPerInterval(Scheduling.Year, leapYearDate, true);

            //Act
            var adviceTriggers = AdviceTriggerFactory.CreateFrom(leapYearDate, Scheduling.Year).ToList();

            //Assert
            var adviceTrigger = Assert.Single(adviceTriggers);

            Assert.Equal(expectedInterval, adviceTrigger.Cron);
        }
Пример #5
0
        public void CreateFromAlarmDateAndScheduleReturns_1_Trigger_With_LastDayInMonth_If_31_Is_Selected(Scheduling scheduling, int month, int day)
        {
            //Arrange
            var alarmDate        = new DateTime(2000, month, day);
            var expectedInterval = CronStringHelper.CronPerInterval(scheduling, new DateTime(2000, month, day), true);

            //Act
            var adviceTriggers = AdviceTriggerFactory.CreateFrom(alarmDate, scheduling).ToList();

            //Assert
            var adviceTrigger = Assert.Single(adviceTriggers);

            Assert.False(adviceTrigger.PartitionId.HasValue);
            Assert.Equal(expectedInterval, adviceTrigger.Cron);
        }
Пример #6
0
        public void CreateFromAlarmDateAndScheduleReturns_2_Triggers_For_SemiAnnualTrigger_Trigger_With_Day_Which_Conflicts_With_February(int month, int day)
        {
            //Arrange
            var alarmDate          = new DateTime(2000, month, day);
            var expectedPartitions = Enumerable.Range(0, 2).ToList();
            var expectedCronJobs   = new[]
            {
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(2000, 2, 28), true),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(2000, 8, day))
            };

            //Act
            var adviceTriggers = AdviceTriggerFactory.CreateFrom(alarmDate, Scheduling.Semiannual).ToList();

            //Assert
            AssertCreatedJobs(adviceTriggers, expectedPartitions, expectedCronJobs);
        }
Пример #7
0
        public void CreateFromAlarmDateAndScheduleReturns_With_SemiAnnual_Interval_HandlesAlarmDate_InLeap_Year()
        {
            //Arrange
            var leapYearDate       = new DateTime(2020, 2, 29);
            var expectedPartitions = Enumerable.Range(0, 2).ToList();
            var expectedCronJobs   = new[]
            {
                CronStringHelper.CronPerInterval(Scheduling.Year, leapYearDate, true),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(leapYearDate.Year, leapYearDate.Month + 6, leapYearDate.Day))
            };

            //Act
            var adviceTriggers = AdviceTriggerFactory.CreateFrom(leapYearDate, Scheduling.Semiannual).ToList();

            //Assert
            AssertCreatedJobs(adviceTriggers, expectedPartitions, expectedCronJobs);
        }
Пример #8
0
        private static string[] CreateExpectedCronForMonthlyInterval(int year, int day, bool expectFebruaryLastDayInMonth)
        {
            var expectedCronJobs = new[]
            {
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 1, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 2, expectFebruaryLastDayInMonth ? 28 : day), expectFebruaryLastDayInMonth),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 3, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 4, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 5, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 6, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 7, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 8, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 9, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 10, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 11, day)),
                CronStringHelper.CronPerInterval(Scheduling.Year, new DateTime(year, 12, day))
            };

            return(expectedCronJobs);
        }
        private async Task DoProcess()
        {
            var jobs = _typeFinder
                       .Find(type => type != null && type.IsPublic && type.HasAttribute <ScheduledJobAttribute>())
                       .Select(e => new
            {
                Class     = e,
                Attribute = e.GetAttribute <ScheduledJobAttribute>()
            })
                       .ToList();

            // deactivate all jobs which are missing in the code
            var dbItems = await _jobRepo.GetAll().ToListAsync();

            var toDelete = dbItems.Where(i => !jobs.Any(j => j.Attribute.Uid == i.Id)).ToList();

            foreach (var scheduledJob in toDelete)
            {
                await _jobRepo.DeleteAsync(scheduledJob);
            }

            if (!jobs.Any())
            {
                return;
            }

            foreach (var jobInfo in jobs)
            {
                try
                {
                    using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
                    {
                        var existingJob = await _jobRepo.GetAll().FirstOrDefaultAsync(j => j.Id == jobInfo.Attribute.Uid);

                        // job already exists - activate  if inactive it and continue processing
                        // note: the user can't create/delete jobs manually, so we assume that the job was inactivated by this bootstrapper
                        if (existingJob != null)
                        {
                            if (existingJob.IsDeleted)
                            {
                                existingJob.IsDeleted     = false;
                                existingJob.DeletionTime  = null;
                                existingJob.DeleterUserId = null;
                                await _jobRepo.UpdateAsync(existingJob);
                            }

                            continue;
                        }
                    }

                    // create job and default trigger only if the job is missing in the DB
                    var job = new ScheduledJob()
                    {
                        Id             = jobInfo.Attribute.Uid,
                        JobName        = jobInfo.Class.Name,
                        JobNamespace   = jobInfo.Class.Namespace,
                        StartupMode    = jobInfo.Attribute.StartupMode,
                        JobStatus      = JobStatus.Active,
                        JobDescription = jobInfo.Attribute.Description
                    };

                    await _jobRepo.InsertAsync(job);

                    // create a trigger
                    if (jobInfo.Attribute.StartupMode == StartUpMode.Automatic &&
                        CronStringHelper.IsValidCronExpression(jobInfo.Attribute.CronString ?? string.Empty))
                    {
                        var trigger = new ScheduledJobTrigger()
                        {
                            Job         = job,
                            Description = "Default trigger (created automatically)",
                            CronString  = jobInfo.Attribute.CronString
                        };

                        await _triggerRepo.InsertAsync(trigger);
                    }

                    await _unitOfWorkManager.Current.SaveChangesAsync();
                }
                catch (Exception e)
                {
                    throw new Exception($"An error occured during bootstrapping of the scheduled job {jobInfo.Attribute.Uid}", e);
                }
            }

            // sync to Hangfire
            await _jobManager.EnqueueAllAsync();
        }
Пример #10
0
 private static AdviceTrigger SetupAdviceTrigger(Scheduling schedule, DateTime alarmDate, Maybe <int> partitionId, bool enforceLastDayInMonth = false)
 {
     return(new AdviceTrigger(CronStringHelper.CronPerInterval(schedule, alarmDate, enforceLastDayInMonth), partitionId));
 }