1 module scheduled.job;
2 
3 import std.datetime;
4 import scheduled.schedule;
5 
6 /**
7  * A job is a task which is submitted to the scheduler, to be run one or more
8  * times, according to a given schedule.
9  */
10 public interface Job {
11     /**
12      * The method which is called to execute this job.
13      */
14     public void run();
15 }
16 
17 /** 
18  * Simple job that executes a function.
19  */
20 public class FunctionJob : Job {
21     /** 
22      * The function to execute when this job is run.
23      */
24     private void function() fn;
25 
26     /** 
27      * Constructs a job that will run the given function.
28      * Params:
29      *   fn = The function to execute.
30      */
31     this(void function() fn) {
32         this.fn = fn;
33     }
34 
35     /** 
36      * Runs the function.
37      */
38     override public void run() {
39         this.fn();
40     }
41 }
42 
43 /** 
44  * Represents a pairing of a Job with a schedule.
45  */
46 public final class ScheduledJob {
47     /** 
48      * The component which is used to obtain current timestamps.
49      */
50     private const CurrentTimeProvider timeProvider;
51 
52     /** 
53      * The schedule which defines when the associated job will run.
54      */
55     private JobSchedule schedule;
56 
57     /** 
58      * The job which will run according to the associated schedule.
59      */
60     private Job job;
61 
62     /** 
63      * Constructs a new pairing of a job and a schedule.
64      * Params:
65      *   job = The job which is scheduled.
66      *   schedule = The schedule that defines when the job will run.
67      *   timeProvider = Provider of current timestamps.
68      */
69     public this(Job job, JobSchedule schedule, CurrentTimeProvider timeProvider) {
70         this.job = job;
71         this.schedule = schedule;
72         this.timeProvider = timeProvider;
73     }
74 
75     /** 
76      * Constructs a new pairing of a job and a schedule, with the default
77      * system time provider.
78      * Params:
79      *   job = The job which is scheduled.
80      *   schedule = The schedule that defines when the job will run.
81      */
82     public this(Job job, JobSchedule schedule) {
83         this(job, schedule, new SysTimeProvider);
84     }
85 
86     /** 
87      * Gets the schedule from this pairing.
88      * Returns: The schedule.
89      */
90     public JobSchedule getSchedule() {
91         return this.schedule;
92     }
93 
94     /** 
95      * Gets the job from this pairing.
96      * Returns: The job.
97      */
98     public Job getJob() {
99         return this.job;
100     }
101 
102     override int opCmp(Object other) {
103         if (auto otherJob = cast(ScheduledJob) other) {
104             SysTime now = timeProvider.now;
105             auto t1 = this.getSchedule().getNextExecutionTime(now);
106             auto t2 = otherJob.getSchedule().getNextExecutionTime(now);
107             if (t1.isNull && t2.isNull) return 0;
108             if (!t1.isNull && t2.isNull) return 1;
109             if (t1.isNull) return -1;
110             return t2.get.opCmp(t1.get);
111         } else {
112             return 0;
113         }
114     }
115 }