Example #1
0
        /// <summary>
        /// Public only to allow HangFire to access it
        /// </summary>
        /// <param name="adviceId"></param>
        public void CreateOrUpdateJob(int adviceId)
        {
            var advice = AdviceRepository.GetByKey(adviceId);

            if (advice == null || advice.Scheduling == null || advice.AlarmDate == null)
            {
                throw new ArgumentException(nameof(adviceId) + " does not point to a valid id or points to an advice without alarm date or scheduling");
            }

            var adviceAlarmDate  = advice.AlarmDate.Value;
            var adviceScheduling = advice.Scheduling.Value;

            var adviceTriggers = AdviceTriggerFactory.CreateFrom(adviceAlarmDate, adviceScheduling);

            foreach (var adviceTrigger in adviceTriggers)
            {
                var prefix = advice.JobId;
                var jobId  = adviceTrigger.PartitionId.Match(partitionId => CreatePartitionJobId(prefix, partitionId), () => prefix);
                HangfireApi.AddOrUpdateRecurringJob(jobId, () => SendAdvice(adviceId), adviceTrigger.Cron);
            }

            if (advice.StopDate.HasValue)
            {
                //Schedule deactivation to happen the day after the stop date (stop date is "last day alive" for the advice)
                HangfireApi.Schedule(() => DeactivateById(advice.Id), new DateTimeOffset(advice.StopDate.Value.Date.AddDays(1)));
            }

            //If time has passed the trigger time, Hangfire will not fire until the next trigger data so we must force it.
            if (adviceAlarmDate.Date.Equals(OperationClock.Now.Date))
            {
                switch (adviceScheduling)
                {
                case Scheduling.Day:
                case Scheduling.Week:
                case Scheduling.Month:
                case Scheduling.Year:
                case Scheduling.Quarter:
                case Scheduling.Semiannual:
                    var mustScheduleAdviceToday =
                        advice.AdviceSent.Where(x => x.AdviceSentDate.Date == adviceAlarmDate.Date).Any() == false &&
                        WillTriggerInvokeToday() == false;
                    if (mustScheduleAdviceToday)
                    {
                        //Send the first advice now
                        HangfireApi.Schedule(() => SendAdvice(adviceId));
                    }
                    break;

                //Intentional fallthrough - no corrections here
                case Scheduling.Hour:
                case Scheduling.Immediate:
                default:
                    break;
                }
            }
        }
Example #2
0
        public void CreateFromAlarmDateAndScheduleReturns_With_Monthly_Interval_HandlesAlarmDate_InLeap_Year()
        {
            //Arrange
            var leapYearDate       = new DateTime(2020, 2, 29);
            var expectedPartitions = Enumerable.Range(0, 12).ToList();
            var expectedCronJobs   = CreateExpectedCronForMonthlyInterval(leapYearDate.Year, leapYearDate.Day, true);

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

            //Assert
            AssertCreatedJobs(adviceTriggers, expectedPartitions, expectedCronJobs);
        }
Example #3
0
        public void CreateFromAlarmDateAndScheduleReturns_12_Triggers_For_Monthly_Trigger_With_Day(int day)
        {
            //Arrange
            var year               = 2000;
            var alarmDate          = new DateTime(year, 3, day);
            var expectedPartitions = Enumerable.Range(0, 12).ToList();
            var expectedCronJobs   = CreateExpectedCronForMonthlyInterval(year, day, true);

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

            //Assert
            AssertCreatedJobs(adviceTriggers, expectedPartitions, expectedCronJobs);
        }
Example #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);
        }
Example #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);
        }
Example #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);
        }
Example #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);
        }