internal static TimerSchedule Create(TimerTriggerAttribute attribute, INameResolver nameResolver) { TimerSchedule schedule = null; if (!string.IsNullOrEmpty(attribute.ScheduleExpression)) { string resolvedExpression = nameResolver.ResolveWholeString(attribute.ScheduleExpression); CronSchedule cronSchedule = null; if (CronSchedule.TryCreate(resolvedExpression, out cronSchedule)) { schedule = cronSchedule; DateTime[] nextOccurrences = cronSchedule.InnerSchedule.GetNextOccurrences(DateTime.Now, DateTime.Now + TimeSpan.FromMinutes(1)).ToArray(); if (nextOccurrences.Length > 1) { // if there is more than one occurrence due in the next minute, // assume that this is a sub-minute constant schedule and disable // persistence attribute.UseMonitor = false; } else if (!attribute.UseMonitor.HasValue) { // if the user hasn't specified a value // set to true attribute.UseMonitor = true; } } else { TimeSpan periodTimespan = TimeSpan.Parse(resolvedExpression); schedule = new ConstantSchedule(periodTimespan); if (periodTimespan.TotalMinutes < 1) { // for very frequent constant schedules, we want to disable persistence attribute.UseMonitor = false; } else if (!attribute.UseMonitor.HasValue) { // if the user hasn't specified a value // set to true attribute.UseMonitor = true; } } } else { schedule = (TimerSchedule)Activator.CreateInstance(attribute.ScheduleType); if (!attribute.UseMonitor.HasValue) { // if the user hasn't specified a value // set to true attribute.UseMonitor = true; } } return(schedule); }
public void Constructor_CreatesCronSchedule() { TimerTriggerAttribute attribute = new TimerTriggerAttribute("*/15 * * * * *"); Assert.Equal(typeof(CronSchedule), attribute.Schedule.GetType()); DateTime now = new DateTime(2015, 5, 22, 9, 45, 00); DateTime nextOccurrence = attribute.Schedule.GetNextOccurrence(now); Assert.Equal(new TimeSpan(0, 0, 15), nextOccurrence - now); }
public void Constructor_CreatesConstantSchedule() { TimerTriggerAttribute attribute = new TimerTriggerAttribute("00:00:15"); Assert.Equal(typeof(ConstantSchedule), attribute.Schedule.GetType()); DateTime now = DateTime.Now; DateTime nextOccurrence = attribute.Schedule.GetNextOccurrence(now); Assert.Equal(new TimeSpan(0, 0, 15), nextOccurrence - now); }
internal static TimerSchedule Create(TimerTriggerAttribute attribute, INameResolver nameResolver) { TimerSchedule schedule = null; if (!string.IsNullOrEmpty(attribute.ScheduleExpression)) { string resolvedExpression = nameResolver.ResolveWholeString(attribute.ScheduleExpression); CronSchedule cronSchedule = null; TimeSpan periodTimespan; if (CronSchedule.TryCreate(resolvedExpression, out cronSchedule)) { schedule = cronSchedule; DateTime[] nextOccurrences = cronSchedule.InnerSchedule.GetNextOccurrences(DateTime.Now, DateTime.Now + TimeSpan.FromMinutes(1)).ToArray(); if (nextOccurrences.Length > 1) { // if there is more than one occurrence due in the next minute, // assume that this is a sub-minute constant schedule and disable // persistence attribute.UseMonitor = false; } } else if (TimeSpan.TryParse(resolvedExpression, out periodTimespan)) { schedule = new ConstantSchedule(periodTimespan); if (periodTimespan.TotalMinutes < 1) { // for very frequent constant schedules, we want to disable persistence attribute.UseMonitor = false; } } else { throw new ArgumentException("The schedule expression was not recognized as a valid cron expression or timespan string."); } } else { schedule = (TimerSchedule)Activator.CreateInstance(attribute.ScheduleType); } return(schedule); }
internal static TimerSchedule Create(TimerTriggerAttribute attribute, INameResolver nameResolver, ILogger logger) { TimerSchedule schedule = null; if (!string.IsNullOrEmpty(attribute.ScheduleExpression)) { string resolvedExpression = nameResolver.ResolveWholeString(attribute.ScheduleExpression); if (CronSchedule.TryCreate(resolvedExpression, out CronSchedule cronSchedule)) { schedule = cronSchedule; if (attribute.UseMonitor && ShouldDisableScheduleMonitor(cronSchedule, DateTime.Now)) { logger.LogDebug("UseMonitor changed to false based on schedule frequency."); attribute.UseMonitor = false; } } else if (TimeSpan.TryParse(resolvedExpression, out TimeSpan periodTimespan)) { schedule = new ConstantSchedule(periodTimespan); if (attribute.UseMonitor && periodTimespan.TotalMinutes < 1) { // for very frequent constant schedules, we want to disable persistence logger.LogDebug("UseMonitor changed to false based on schedule frequency."); attribute.UseMonitor = false; } } else { throw new ArgumentException(string.Format("The schedule expression '{0}' was not recognized as a valid cron expression or timespan string.", resolvedExpression)); } } else { schedule = (TimerSchedule)Activator.CreateInstance(attribute.ScheduleType); } return(schedule); }
private void CreateTestListener(string expression, bool useMonitor = true) { _attribute = new TimerTriggerAttribute(expression); _attribute.UseMonitor = useMonitor; _config = new TimersConfiguration(); _mockScheduleMonitor = new Mock<ScheduleMonitor>(MockBehavior.Strict); _config.ScheduleMonitor = _mockScheduleMonitor.Object; _mockTriggerExecutor = new Mock<ITriggeredFunctionExecutor>(MockBehavior.Strict); FunctionResult result = new FunctionResult(true); _mockTriggerExecutor.Setup(p => p.TryExecuteAsync(It.IsAny<TriggeredFunctionData>(), It.IsAny<CancellationToken>())) .Callback<TriggeredFunctionData, CancellationToken>((mockFunctionData, mockToken) => { _triggeredFunctionData = mockFunctionData; }) .Returns(Task.FromResult(result)); _listener = new TimerListener(_attribute, _testTimerName, _config, _mockTriggerExecutor.Object, new TestTraceWriter()); }