/// <summary> /// For schedules with an occurrence more frequent than 1 minute, we disable schedule monitoring. /// </summary> /// <param name="cronSchedule">The cron schedule to check.</param> /// <returns>True if monitoring should be disabled, false otherwise.</returns> internal static bool ShouldDisableScheduleMonitor(CronSchedule cronSchedule, DateTime now) { // take the original expression minus the seconds portion string expression = cronSchedule.InnerSchedule.ToString(); var expressions = expression.Split(' '); // If any of the minute or higher fields contain non-wildcard expressions // the schedule can be longer than 1 minute. I.e. the only way for all occurrences // to be less than or equal to a minute is if all these fields are wild ("* * * * *"). bool hasNonSecondRestrictions = !expressions.Skip(1).All(p => p == "*"); if (!hasNonSecondRestrictions) { // If to here, we know we're dealing with a schedule of the form X * * * * * // so we just need to consider the seconds expression to determine if it occurs // more frequently than 1 minute. // E.g. an expression like */10 * * * * * occurs every 10 seconds, while an // expression like 0 * * * * * occurs exactly once per minute. DateTime[] nextOccurrences = cronSchedule.InnerSchedule.GetNextOccurrences(now, 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 return(true); } } return(false); }
/// <summary> /// Constructs a new instance based on the schedule expression passed in./> /// </summary> /// <param name="expression">A schedule expression. This can either be a crontab expression /// <a href="http://en.wikipedia.org/wiki/Cron#CRON_expression"/> or a <see cref="TimeSpan"/> string.</param> public TimerTriggerAttribute(string expression) { CronSchedule cronSchedule = null; if (CronSchedule.TryCreate(expression, 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 UseMonitor = false; } else { UseMonitor = true; } } else { TimeSpan periodTimespan = TimeSpan.Parse(expression); Schedule = new ConstantSchedule(periodTimespan); // for very frequent constant schedules, we want to disable persistence UseMonitor = periodTimespan.TotalMinutes >= 1; } }
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); }
internal static bool TryCreate(string cronExpression, out CronSchedule cronSchedule) { cronSchedule = null; CrontabSchedule.ParseOptions options = new CrontabSchedule.ParseOptions() { IncludingSeconds = true }; CrontabSchedule crontabSchedule = CrontabSchedule.TryParse(cronExpression, options); if (crontabSchedule != null) { cronSchedule = new CronSchedule(crontabSchedule); return true; } return false; }
internal static bool TryCreate(string cronExpression, out CronSchedule cronSchedule) { cronSchedule = null; CrontabSchedule.ParseOptions options = new CrontabSchedule.ParseOptions() { IncludingSeconds = true }; CrontabSchedule crontabSchedule = CrontabSchedule.TryParse(cronExpression, options); if (crontabSchedule != null) { cronSchedule = new CronSchedule(crontabSchedule); return(true); } return(false); }
internal static bool TryCreate(string cronExpression, out CronSchedule cronSchedule) { cronSchedule = null; if (cronExpression != null) { var options = CreateParseOptions(cronExpression); CrontabSchedule crontabSchedule = CrontabSchedule.TryParse(cronExpression, options); if (crontabSchedule != null) { cronSchedule = new CronSchedule(crontabSchedule); return(true); } } return(false); }
public void GetNextOccurrence_ThreeDaySchedule_MultipleScheduleIterations() { // 11:59AM on Mondays, Tuesdays, Wednesdays, Thursdays and Fridays CronSchedule schedule = new CronSchedule("0 59 11 * * 1-5"); DateTime now = new DateTime(2015, 5, 23, 9, 0, 0); TimeSpan expectedTime = new TimeSpan(11, 59, 0); for (int i = 1; i <= 5; i++) { DateTime nextOccurrence = schedule.GetNextOccurrence(now); Assert.Equal((DayOfWeek)i, nextOccurrence.DayOfWeek); Assert.Equal(expectedTime, nextOccurrence.TimeOfDay); now = nextOccurrence + TimeSpan.FromSeconds(1); } }
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); }
public void ToString_ReturnsExpectedValue() { CronSchedule schedule = new CronSchedule("0 59 11 * * 1-5"); Assert.Equal("Cron: '0 59 11 * * 1-5'", schedule.ToString()); }