1 /** 2 * Defines the interface which all schedules implement, and some utilities that 3 * go along with the schedule concept. 4 */ 5 module scheduled.schedule; 6 7 import std.datetime; 8 import std.typecons; 9 10 /** 11 * A schedule that governs when a job should be executed. 12 */ 13 public interface JobSchedule { 14 /** 15 * Gets the timestamp at which the scheduler should plan to execute a job 16 * with this schedule next. 17 */ 18 Nullable!SysTime getNextExecutionTime(SysTime currentTime) const; 19 20 /** 21 * Marks the schedule as having been executed at the given time. 22 */ 23 void markExecuted(SysTime executionTime); 24 25 /** 26 * Tells whether the schedule is repeating; that jobs with this schedule 27 * should be re-queued after being executed. 28 * Returns: True if this schedule is repeating, or false otherwise. 29 */ 30 bool isRepeating() const; 31 } 32 33 /** 34 * Simple wrapper interface for obtaining the current system time. 35 */ 36 public interface CurrentTimeProvider { 37 /** 38 * Gets the current system time. 39 * Returns: The current system time. 40 */ 41 SysTime now() const; 42 } 43 44 /** 45 * Standard implementation of the current time provider, which simply returns 46 * the current system time. 47 */ 48 public class SysTimeProvider : CurrentTimeProvider { 49 SysTime now() const { 50 return Clock.currTime; 51 } 52 } 53 54 /** 55 * Tests the functionality of the system time provider. 56 */ 57 unittest { 58 import core.thread; 59 auto provider = new SysTimeProvider; 60 for (int i = 0; i < 10; i++) { 61 auto duration = provider.now - Clock.currTime; 62 assert(duration < msecs(100), "System time provider's time does not match expected."); 63 Thread.sleep(msecs(10)); 64 } 65 } 66 67 /** 68 * Implementation of the current time provider which always returns a fixed 69 * value, useful for testing. 70 */ 71 public class FixedTimeProvider : CurrentTimeProvider { 72 private SysTime currentTime; 73 74 this(SysTime currentTime) { 75 this.currentTime = currentTime; 76 } 77 78 SysTime now() const { 79 return this.currentTime; 80 } 81 82 public void incrementTime(Duration dur) { 83 this.currentTime += dur; 84 } 85 86 public void setTime(SysTime newTime) { 87 this.currentTime = newTime; 88 } 89 } 90 91 /** 92 * Tests the functionality of the fixed time provider. 93 */ 94 unittest { 95 import core.thread; 96 SysTime time = SysTime(DateTime(2021, 9, 22, 22, 34, 57)); 97 auto provider = new FixedTimeProvider(time); 98 assert(provider.now == time, "Fixed time provider's time does not match expected."); 99 Thread.sleep(seconds(1)); 100 assert(provider.now == time, "Fixed time provider's time does not match expected."); 101 }