summaryrefslogtreecommitdiff
path: root/src/stable/minicron.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/minicron.h')
-rw-r--r--src/stable/minicron.h630
1 files changed, 315 insertions, 315 deletions
diff --git a/src/stable/minicron.h b/src/stable/minicron.h
index 53e5156..953b82a 100644
--- a/src/stable/minicron.h
+++ b/src/stable/minicron.h
@@ -16,321 +16,321 @@
16 16
17namespace Bu 17namespace Bu
18{ 18{
19 /** 19 /**
20 * A simple cron like system designed to be embedded in any program. This 20 * A simple cron like system designed to be embedded in any program. This
21 * class creates a simple cron system that can run any number of jobs at 21 * class creates a simple cron system that can run any number of jobs at
22 * customizable intervals or schedules. It does not support some of the 22 * customizable intervals or schedules. It does not support some of the
23 * more complex scheduling that some cron systems can do such as load 23 * more complex scheduling that some cron systems can do such as load
24 * balancing directly, but this could be done on the job side. 24 * balancing directly, but this could be done on the job side.
25 * 25 *
26 * This system is synchronous, it does not use any threads on it's own, but 26 * This system is synchronous, it does not use any threads on it's own, but
27 * it is threadsafe, so a cron thread could be created if desired. 27 * it is threadsafe, so a cron thread could be created if desired.
28 * 28 *
29 * The operation is fairly simple, jobs can be added at any time, and use 29 * The operation is fairly simple, jobs can be added at any time, and use
30 * any timer they would like, even custom timers. When it is time for a 30 * any timer they would like, even custom timers. When it is time for a
31 * job to be run it signals the slot provided when the job was added. Every 31 * job to be run it signals the slot provided when the job was added. Every
32 * job slot recieves a handle to the job object so that it may control it's 32 * job slot recieves a handle to the job object so that it may control it's
33 * own lifetime and get information about itself. In addition, every job 33 * own lifetime and get information about itself. In addition, every job
34 * is assigned a unique ID that can be used to control it's operation 34 * is assigned a unique ID that can be used to control it's operation
35 * at any time. 35 * at any time.
36 * 36 *
37 * By default a job will continually reschedule itself after being run 37 * By default a job will continually reschedule itself after being run
38 * unless it calls stop() on it's job object, it is removed using 38 * unless it calls stop() on it's job object, it is removed using
39 * removeJob() on the cron object, or it is added with addJobOnce. 39 * removeJob() on the cron object, or it is added with addJobOnce.
40 * 40 *
41 *@todo A minor change to the job execution system could allow a Timer to 41 *@todo A minor change to the job execution system could allow a Timer to
42 * defer or reschedule execution instead of the job executing. This would, 42 * defer or reschedule execution instead of the job executing. This would,
43 * in effect, allow us to do every type of interesting scheduling that 43 * in effect, allow us to do every type of interesting scheduling that
44 * systems like fcron offer, including time constrained load-balanced 44 * systems like fcron offer, including time constrained load-balanced
45 * execution. 45 * execution.
46 */ 46 */
47 class MiniCron 47 class MiniCron
48 { 48 {
49 public: 49 public:
50 class Job; 50 class Job;
51 class Timer; 51 class Timer;
52 typedef Bu::Signal1<void, Bu::MiniCron::Job &> CronSignal; 52 typedef Bu::Signal1<void, Bu::MiniCron::Job &> CronSignal;
53 typedef int JobId; 53 typedef int JobId;
54 54
55 MiniCron(); 55 MiniCron();
56 virtual ~MiniCron(); 56 virtual ~MiniCron();
57 57
58 /** 58 /**
59 * Tells you if there are jobs registered in the MiniCron. 59 * Tells you if there are jobs registered in the MiniCron.
60 *@returns true if there are jobs, false otherwise. 60 *@returns true if there are jobs, false otherwise.
61 */ 61 */
62 virtual bool hasJobs(); 62 virtual bool hasJobs();
63 63
64 /** 64 /**
65 * If there are jobs, tells you the time the next one will execute. 65 * If there are jobs, tells you the time the next one will execute.
66 *@returns The timestamp that the next job will execute at. 66 *@returns The timestamp that the next job will execute at.
67 */ 67 */
68 virtual time_t getNextRun(); 68 virtual time_t getNextRun();
69 69
70 /** 70 /**
71 * Tells you the time the job matching jid will run next. 71 * Tells you the time the job matching jid will run next.
72 *@returns The timestamp that the job jid will next run. 72 *@returns The timestamp that the job jid will next run.
73 */ 73 */
74 virtual time_t getNextRun( JobId jid ); 74 virtual time_t getNextRun( JobId jid );
75 75
76 /** 76 /**
77 * Call this regularly to execute all jobs that should be executed. 77 * Call this regularly to execute all jobs that should be executed.
78 * This will loop until all jobs who's run time match the current time 78 * This will loop until all jobs who's run time match the current time
79 * or are below the current time (we've missed them). 79 * or are below the current time (we've missed them).
80 * If there is nothing to run, the runtime of this funcion is constant, 80 * If there is nothing to run, the runtime of this funcion is constant,
81 * it is very fast. Otherwise it executes at log(N) per job run, 81 * it is very fast. Otherwise it executes at log(N) per job run,
82 * O(N*log(N)). 82 * O(N*log(N)).
83 */ 83 */
84 virtual void poll(); 84 virtual void poll();
85 85
86 /** 86 /**
87 * Add a job for repeated scheduling. Pass in a slot to signal, and a 87 * Add a job for repeated scheduling. Pass in a slot to signal, and a
88 * Timer object to use to do the scheduling. This function returns a 88 * Timer object to use to do the scheduling. This function returns a
89 * JobId which can be used at a later time to control the execution of 89 * JobId which can be used at a later time to control the execution of
90 * the job. 90 * the job.
91 */ 91 */
92 virtual JobId addJob( const Bu::String &sName, CronSignal sigJob, 92 virtual JobId addJob( const Bu::String &sName, CronSignal sigJob,
93 const Timer &t ); 93 const Timer &t );
94 94
95 /** 95 /**
96 * Add a job for one time scheduling. Pass in a slot to signal, and a 96 * Add a job for one time scheduling. Pass in a slot to signal, and a
97 * Timer object to use to schodule the one run of this job. This 97 * Timer object to use to schodule the one run of this job. This
98 * function returns a JobId which can be used at a later time to control 98 * function returns a JobId which can be used at a later time to control
99 * the execution of the job. 99 * the execution of the job.
100 */ 100 */
101 virtual JobId addJobOnce( const Bu::String &sName, CronSignal sigJob, 101 virtual JobId addJobOnce( const Bu::String &sName, CronSignal sigJob,
102 const Timer &t ); 102 const Timer &t );
103 103
104 /** 104 /**
105 * Remove a job, preventing all future runs of the job. If there is no 105 * Remove a job, preventing all future runs of the job. If there is no
106 * job matching the given JobId then nothing will happen. However, this 106 * job matching the given JobId then nothing will happen. However, this
107 * function is relatively expensive compared to the others in this class 107 * function is relatively expensive compared to the others in this class
108 * and has a worse case runtime of 2*N*log(N), still not that bad, and 108 * and has a worse case runtime of 2*N*log(N), still not that bad, and
109 * a O(N*log(N)). 109 * a O(N*log(N)).
110 */ 110 */
111 virtual void removeJob( JobId jid ); 111 virtual void removeJob( JobId jid );
112 112
113 /** 113 /**
114 * Executes the job specified right now. If bReschedule is true then 114 * Executes the job specified right now. If bReschedule is true then
115 * the job is then removed from the queue and rescheduled as though 115 * the job is then removed from the queue and rescheduled as though
116 * it's time had come naturally to be run. Otherwise, it's run without 116 * it's time had come naturally to be run. Otherwise, it's run without
117 * interrupting the normal schedule. 117 * interrupting the normal schedule.
118 */ 118 */
119 virtual void runJob( JobId jid, bool bReschedule=false ); 119 virtual void runJob( JobId jid, bool bReschedule=false );
120 120
121 /** 121 /**
122 * Executes the job specified right now. If bReschedule is true then 122 * Executes the job specified right now. If bReschedule is true then
123 * the job is then removed from the queue and rescheduled as though 123 * the job is then removed from the queue and rescheduled as though
124 * it's time had come naturally to be run. Otherwise, it's run without 124 * it's time had come naturally to be run. Otherwise, it's run without
125 * interrupting the normal schedule. 125 * interrupting the normal schedule.
126 */ 126 */
127 virtual void runJob( const Bu::String &sName, bool bReschedule=false ); 127 virtual void runJob( const Bu::String &sName, bool bReschedule=false );
128 128
129 class JobInfo 129 class JobInfo
130 { 130 {
131 public: 131 public:
132 JobInfo( const Bu::String &sName, JobId jid, time_t tNext ); 132 JobInfo( const Bu::String &sName, JobId jid, time_t tNext );
133 virtual ~JobInfo(); 133 virtual ~JobInfo();
134 134
135 bool operator<( const JobInfo &rhs ) const; 135 bool operator<( const JobInfo &rhs ) const;
136 136
137 Bu::String sName; 137 Bu::String sName;
138 JobId jid; 138 JobId jid;
139 time_t tNext; 139 time_t tNext;
140 }; 140 };
141 typedef Bu::List<JobInfo> JobInfoList; 141 typedef Bu::List<JobInfo> JobInfoList;
142 142
143 JobInfoList getJobInfo(); 143 JobInfoList getJobInfo();
144 144
145 /** 145 /**
146 * The baseclass for timer/schedulers for MiniCron jobs. Classes that 146 * The baseclass for timer/schedulers for MiniCron jobs. Classes that
147 * inherit from this are used to determine when jobs will run and at 147 * inherit from this are used to determine when jobs will run and at
148 * what interval. 148 * what interval.
149 */ 149 */
150 class Timer 150 class Timer
151 { 151 {
152 public: 152 public:
153 Timer(); 153 Timer();
154 virtual ~Timer(); 154 virtual ~Timer();
155 155
156 /** 156 /**
157 * Called by MiniCron when each job is run to determine the next 157 * Called by MiniCron when each job is run to determine the next
158 * time that a job should be run. When a job is run, this function 158 * time that a job should be run. When a job is run, this function
159 * is actually called before the job is executed again so that the 159 * is actually called before the job is executed again so that the
160 * job can tell when the next time it will be run will be. 160 * job can tell when the next time it will be run will be.
161 */ 161 */
162 virtual time_t nextTime()=0; 162 virtual time_t nextTime()=0;
163 163
164 /** 164 /**
165 * This function should return a copy of the child class. 165 * This function should return a copy of the child class.
166 */ 166 */
167 virtual Timer *clone() const = 0; 167 virtual Timer *clone() const = 0;
168 }; 168 };
169 169
170 /** 170 /**
171 * Execute the job every tInterval seconds, also you can delay the 171 * Execute the job every tInterval seconds, also you can delay the
172 * first run by a different amount of time from the job's creation. 172 * first run by a different amount of time from the job's creation.
173 */ 173 */
174 class TimerInterval : public Timer 174 class TimerInterval : public Timer
175 { 175 {
176 public: 176 public:
177 TimerInterval( time_t tFirst, time_t tInterval ); 177 TimerInterval( time_t tFirst, time_t tInterval );
178 virtual ~TimerInterval(); 178 virtual ~TimerInterval();
179 179
180 virtual time_t nextTime(); 180 virtual time_t nextTime();
181 virtual Timer *clone() const 181 virtual Timer *clone() const
182 { return new TimerInterval( *this ); } 182 { return new TimerInterval( *this ); }
183 private: 183 private:
184 time_t tNext; 184 time_t tNext;
185 time_t tInterval; 185 time_t tInterval;
186 }; 186 };
187 187
188 /** 188 /**
189 * A much more general timer class that can be used for much more 189 * A much more general timer class that can be used for much more
190 * "cron-like" functionality. The constructor takes a string that 190 * "cron-like" functionality. The constructor takes a string that
191 * describes the times that the job should be run. At the moment the 191 * describes the times that the job should be run. At the moment the
192 * following schemes are understood: 192 * following schemes are understood:
193 * 193 *
194 * "daily [hour] [minute]" 194 * "daily [hour] [minute]"
195 * "hourly [minute]" 195 * "hourly [minute]"
196 * "weekly [day] [hour] [minute]" 196 * "weekly [day] [hour] [minute]"
197 * 197 *
198 * In these examples each word in [brackets] represents a number that 198 * In these examples each word in [brackets] represents a number that
199 * matches the data type in the brackets. [day] is the number of days 199 * matches the data type in the brackets. [day] is the number of days
200 * since sunday, 0-6. You can also use lowercase three character 200 * since sunday, 0-6. You can also use lowercase three character
201 * abbreviations for the day names. 201 * abbreviations for the day names.
202 * 202 *
203 * Many more forms follow. 203 * Many more forms follow.
204 */ 204 */
205 class TimerBasic : public Timer 205 class TimerBasic : public Timer
206 { 206 {
207 public: 207 public:
208 TimerBasic( const Bu::String &s ); 208 TimerBasic( const Bu::String &s );
209 virtual ~TimerBasic(); 209 virtual ~TimerBasic();
210 210
211 virtual time_t nextTime(); 211 virtual time_t nextTime();
212 virtual Timer *clone() const 212 virtual Timer *clone() const
213 { return new TimerBasic( *this ); } 213 { return new TimerBasic( *this ); }
214 214
215 private: 215 private:
216 enum Token 216 enum Token
217 { 217 {
218 tokDaily, 218 tokDaily,
219 tokHourly, 219 tokHourly,
220 tokWeekly, 220 tokWeekly,
221 tokMonthly, 221 tokMonthly,
222 tokYearly, 222 tokYearly,
223 valInt, 223 valInt,
224 tokErr, 224 tokErr,
225 tokEos 225 tokEos
226 }; 226 };
227 Token lex( Bu::String::const_iterator &i ); 227 Token lex( Bu::String::const_iterator &i );
228 int lexInt( Bu::String::const_iterator &i ); 228 int lexInt( Bu::String::const_iterator &i );
229 int iVal; //< A temp variable for parsing. 229 int iVal; //< A temp variable for parsing.
230 time_t tLast; 230 time_t tLast;
231 Bu::String sSpec; 231 Bu::String sSpec;
232 }; 232 };
233 233
234 /** 234 /**
235 * Represents a MiniCron Job. This class is used for both internal 235 * Represents a MiniCron Job. This class is used for both internal
236 * job management as well as job slot interaction and control. Objects 236 * job management as well as job slot interaction and control. Objects
237 * of this class are passed into the slots that are signaled when a job 237 * of this class are passed into the slots that are signaled when a job
238 * is executed. 238 * is executed.
239 */ 239 */
240 class Job 240 class Job
241 { 241 {
242 friend class Bu::MiniCron; 242 friend class Bu::MiniCron;
243 private: 243 private:
244 Job( const Bu::String &sName, JobId jid, bool bRepeat=true ); 244 Job( const Bu::String &sName, JobId jid, bool bRepeat=true );
245 virtual ~Job(); 245 virtual ~Job();
246 246
247 public: 247 public:
248 248
249 /** 249 /**
250 * Execute this job once, increment the runcount and schedule the 250 * Execute this job once, increment the runcount and schedule the
251 * next occurance of it. 251 * next occurance of it.
252 */ 252 */
253 void run( bool bReschedule=true ); 253 void run( bool bReschedule=true );
254 254
255 /** 255 /**
256 * Get the time this job will next run. 256 * Get the time this job will next run.
257 */ 257 */
258 time_t getNextRun() const; 258 time_t getNextRun() const;
259 259
260 /** 260 /**
261 * Compute the time this job will next run. 261 * Compute the time this job will next run.
262 */ 262 */
263 void calcNextRun(); 263 void calcNextRun();
264 264
265 /** 265 /**
266 * Replace the current job timer with a new one, this will trigger 266 * Replace the current job timer with a new one, this will trigger
267 * a re-schedule. 267 * a re-schedule.
268 */ 268 */
269 void setTimer( const Timer &t ); 269 void setTimer( const Timer &t );
270 270
271 /** 271 /**
272 * Stop execution of this job, never execute this job again. 272 * Stop execution of this job, never execute this job again.
273 */ 273 */
274 void stop(); 274 void stop();
275 275
276 /** 276 /**
277 * Undo a previous stop. This will cause a job that has been 277 * Undo a previous stop. This will cause a job that has been
278 * stopped or even added with addJobOnce to be set for repeated 278 * stopped or even added with addJobOnce to be set for repeated
279 * scheduling. 279 * scheduling.
280 */ 280 */
281 void resume(); 281 void resume();
282 282
283 /** 283 /**
284 * Get the unique ID of this job. 284 * Get the unique ID of this job.
285 */ 285 */
286 JobId getId() const; 286 JobId getId() const;
287 287
288 /** 288 /**
289 * Get the timestamp this job was created. 289 * Get the timestamp this job was created.
290 */ 290 */
291 time_t getTimeCreated() const; 291 time_t getTimeCreated() const;
292 292
293 /** 293 /**
294 * Get the current run count of this job, how many times it has been 294 * Get the current run count of this job, how many times it has been
295 * executed. This is incremented before the slot is signaled. 295 * executed. This is incremented before the slot is signaled.
296 */ 296 */
297 int getRunCount() const; 297 int getRunCount() const;
298 298
299 /** 299 /**
300 * Get the next time that this job will be run. Certain timers may 300 * Get the next time that this job will be run. Certain timers may
301 * have the ability to delay job executions, so this is the earliest 301 * have the ability to delay job executions, so this is the earliest
302 * time that the job may run. 302 * time that the job may run.
303 */ 303 */
304 time_t getNextRunTime() const; 304 time_t getNextRunTime() const;
305 305
306 /** 306 /**
307 * Gets the name that was set when the job was created. 307 * Gets the name that was set when the job was created.
308 */ 308 */
309 Bu::String getName() const; 309 Bu::String getName() const;
310 310
311 private: 311 private:
312 Bu::String sName; 312 Bu::String sName;
313 CronSignal sigJob; 313 CronSignal sigJob;
314 time_t tNextRun; 314 time_t tNextRun;
315 Timer *pTimer; 315 Timer *pTimer;
316 bool bContinue; 316 bool bContinue;
317 JobId jid; 317 JobId jid;
318 time_t tAdded; 318 time_t tAdded;
319 int iRunCount; 319 int iRunCount;
320 }; 320 };
321 321
322 private: 322 private:
323 struct JobPtrCmp 323 struct JobPtrCmp
324 { 324 {
325 bool operator()( const Job *pLeft, const Job *pRight ) 325 bool operator()( const Job *pLeft, const Job *pRight )
326 { 326 {
327 return pLeft->tNextRun < pRight->tNextRun; 327 return pLeft->tNextRun < pRight->tNextRun;
328 } 328 }
329 }; 329 };
330 typedef Bu::Heap<Job *, JobPtrCmp> JobHeap; 330 typedef Bu::Heap<Job *, JobPtrCmp> JobHeap;
331 JobHeap hJobs; 331 JobHeap hJobs;
332 JobId jidNext; 332 JobId jidNext;
333 }; 333 };
334}; 334};
335 335
336#endif 336#endif