Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using FubuTestingSupport;
using FubuTransportation.ScheduledJobs;
using FubuTransportation.ScheduledJobs.Execution;
using FubuTransportation.ScheduledJobs.Persistence;
using NUnit.Framework;

namespace FubuTransportation.Testing.ScheduledJobs
Expand Down Expand Up @@ -56,6 +56,82 @@ protected override void beforeEach()
nextScheduledTime = ClassUnderTest.ScheduleNextTime(LocalSystemTime, null);
}

[Test]
public void next_scheduled_time_should_be_right_now()
{
nextScheduledTime.LocalDateTime.ShouldEqual(DateTime.Today.AddHours(7).AddMinutes(33)); // Today 7:33am
}
}

[TestFixture]
public class when_scheduling_every_day_past_specified_time_within_grace_period_and_no_last_execution : InteractionContext<EveryDayAtSpecificTime>
{
private DateTimeOffset nextScheduledTime;

protected override void beforeEach()
{
Container.Inject(new EveryDayAtSpecificTime(hour: 07, minute: 33)); // 7:33am
LocalSystemTime = DateTime.Today.AddHours(7).AddMinutes(37); // 7:37am
nextScheduledTime = ClassUnderTest.ScheduleNextTime(LocalSystemTime, null);
}

[Test]
public void next_scheduled_time_should_be_slightly_in_past()
{
nextScheduledTime.LocalDateTime.ShouldEqual(DateTime.Today.AddHours(7).AddMinutes(33)); // Today 7:33am
}
}

[TestFixture]
public class when_scheduling_every_day_past_specified_time_outside_grace_period : InteractionContext<EveryDayAtSpecificTime>
{
private DateTimeOffset nextScheduledTime;

protected override void beforeEach()
{
Container.Inject(new EveryDayAtSpecificTime(hour: 07, minute: 33)); // 7:33am
LocalSystemTime = DateTime.Today.AddHours(7).AddMinutes(53); // 7:53am
nextScheduledTime = ClassUnderTest.ScheduleNextTime(LocalSystemTime, null);
}

[Test]
public void next_scheduled_time_should_start_the_next_day()
{
nextScheduledTime.LocalDateTime.ShouldEqual(DateTime.Today.AddDays(1).AddHours(7).AddMinutes(33)); // Tomorrow 7:33am
}
}

[TestFixture]
public class when_scheduling_every_day_past_specified_time_within_grace_period_and_last_execution_not_within_grace_period : InteractionContext<EveryDayAtSpecificTime>
{
private DateTimeOffset nextScheduledTime;

protected override void beforeEach()
{
Container.Inject(new EveryDayAtSpecificTime(hour: 07, minute: 33)); // 7:33am
LocalSystemTime = DateTime.Today.AddHours(7).AddMinutes(37); // 7:37am
nextScheduledTime = ClassUnderTest.ScheduleNextTime(LocalSystemTime, new JobExecutionRecord { Finished = LocalSystemTime.AddHours(-3) }); // 4:37 am
}

[Test]
public void next_scheduled_time_should_be_slightly_in_past()
{
nextScheduledTime.LocalDateTime.ShouldEqual(DateTime.Today.AddHours(7).AddMinutes(33)); // Today 7:33am
}
}

[TestFixture]
public class when_scheduling_every_day_past_specified_time_within_grace_period_and_last_execution_within_grace_period : InteractionContext<EveryDayAtSpecificTime>
{
private DateTimeOffset nextScheduledTime;

protected override void beforeEach()
{
Container.Inject(new EveryDayAtSpecificTime(hour: 07, minute: 33)); // 7:33am
LocalSystemTime = DateTime.Today.AddHours(7).AddMinutes(37); // 7:37am
nextScheduledTime = ClassUnderTest.ScheduleNextTime(LocalSystemTime, new JobExecutionRecord { Finished = LocalSystemTime.AddMinutes(-2) }); // 7:35 am
}

[Test]
public void next_scheduled_time_should_start_the_next_day()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,40 @@

namespace FubuTransportation.ScheduledJobs.Execution
{
// This won't work very well with nodes in different time zones
public class EveryDayAtSpecificTime : IScheduleRule
{
private readonly int _hour;
private readonly int _minute;
private readonly int _gracePeriodInMinutes;

public EveryDayAtSpecificTime(int hour, int minute)
public EveryDayAtSpecificTime(int hour, int minute, int gracePeriodInMinutes = 15)
{
_hour = hour;
_minute = minute;
_gracePeriodInMinutes = gracePeriodInMinutes;
}

public DateTimeOffset ScheduleNextTime(DateTimeOffset currentTime, JobExecutionRecord lastExecution)
{
var localTime = currentTime.ToLocalTime();
var oneAmToday = new DateTime(localTime.Year, localTime.Month, localTime.Day, _hour, _minute, 0, 0, DateTimeKind.Local);
var nextScheduledTime = oneAmToday;
var localcurrentTime = currentTime.ToLocalTime();
var nextScheduledTime = new DateTime(localcurrentTime.Year, localcurrentTime.Month, localcurrentTime.Day, _hour, _minute, 0, 0, DateTimeKind.Local);
var gracePeriodTime = nextScheduledTime.AddMinutes(_gracePeriodInMinutes);

if (localTime.Hour > _hour || (localTime.Hour == _hour && localTime.Minute >= _minute))
var scheduledTimeHasAlreadyPastToday = nextScheduledTime < localcurrentTime;
var withinGracePeriodRightNow = nextScheduledTime < localcurrentTime && localcurrentTime <= gracePeriodTime;

var lastExecutionWithinGracePeriod = false;
if (lastExecution != null)
{
var lastExecutionLocalTime = lastExecution.Finished.ToLocalTime();
lastExecutionWithinGracePeriod = nextScheduledTime < lastExecutionLocalTime && lastExecutionLocalTime <= gracePeriodTime;
}

if (scheduledTimeHasAlreadyPastToday && (!withinGracePeriodRightNow || lastExecutionWithinGracePeriod))
{
// Switch to tomorrow
nextScheduledTime = oneAmToday.AddDays(1);
nextScheduledTime = nextScheduledTime.AddDays(1);
}

return nextScheduledTime.ToUniversalTime();
Expand All @@ -37,4 +50,4 @@ public EveryDayAt1Am() : base(hour: 01, minute: 00)
{}
}
*/
}
}