1Schedule::Cron(3) User Contributed Perl Documentation Schedule::Cron(3)
2
3
4
6 Cron - cron-like scheduler for Perl subroutines
7
9 use Schedule::Cron;
10
11 # Subroutines to be called
12 sub dispatcher {
13 print "ID: ",shift,"\n";
14 print "Args: ","@_","\n";
15 }
16
17 sub check_links {
18 # do something...
19 }
20
21 # Create new object with default dispatcher
22 my $cron = new Schedule::Cron(\&dispatcher);
23
24 # Load a crontab file
25 $cron->load_crontab("/var/spool/cron/perl");
26
27 # Add dynamically crontab entries
28 $cron->add_entry("3 4 * * *",ROTATE => "apache","sendmail");
29 $cron->add_entry("0 11 * * Mon-Fri",\&check_links);
30
31 # Run scheduler
32 $cron->run(detach=>1);
33
35 This module provides a simple but complete cron like scheduler. I.e
36 this module can be used for periodically executing Perl subroutines.
37 The dates and parameters for the subroutines to be called are specified
38 with a format known as crontab entry (see "METHODS", "add_entry()" and
39 crontab(5))
40
41 The philosophy behind "Schedule::Cron" is to call subroutines
42 periodically from within one single Perl program instead of letting
43 "cron" trigger several (possibly different) Perl scripts. Everything
44 under one roof. Furthermore, "Schedule::Cron" provides mechanism to
45 create crontab entries dynamically, which isn't that easy with "cron".
46
47 "Schedule::Cron" knows about all extensions (well, at least all
48 extensions I'm aware of, i.e those of the so called "Vixie" cron) for
49 crontab entries like ranges including 'steps', specification of month
50 and days of the week by name, or coexistence of lists and ranges in the
51 same field. It even supports a bit more (like lists and ranges with
52 symbolic names).
53
55 $cron = new Schedule::Cron($dispatcher,[extra args])
56 Creates a new "Cron" object. $dispatcher is a reference to a
57 subroutine, which will be called by default. $dispatcher will be
58 invoked with the arguments parameter provided in the crontab entry
59 if no other subroutine is specified. This can be either a single
60 argument containing the argument parameter literally has string
61 (default behavior) or a list of arguments when using the "eval"
62 option described below.
63
64 The date specifications must be either provided via a crontab like
65 file or added explicitly with "add_entry()" ("add_entry").
66
67 extra_args can be a hash or hash reference for additional
68 arguments. The following parameters are recognized:
69
70 file => <crontab>
71 Load the crontab entries from <crontab>
72
73 eval => 1
74 Eval the argument parameter in a crontab entry before calling
75 the subroutine (instead of literally calling the dispatcher
76 with the argument parameter as string)
77
78 nofork => 1
79 Don't fork when starting the scheduler. Instead, the jobs are
80 executed within current process. In your executed jobs, you
81 have full access to the global variables of your script and
82 hence might influence other jobs running at a different time.
83 This behaviour is fundamentally different to the 'fork' mode,
84 where each jobs gets its own process and hence a copy of the
85 process space, independent of each other job and the main
86 process. This is due to the nature of the "fork" system call.
87
88 nostatus => 1
89 Do not update status in $0. Set this if you don't want ps to
90 reveal the internals of your application, including job
91 argument lists. Default is 0 (update status).
92
93 skip => 1
94 Skip any pending jobs whose time has passed. This option is
95 only useful in combination with "nofork" where a job might
96 block the execution of the following jobs for quite some time.
97 By default, any pending job is executed even if its scheduled
98 execution time has already passed. With this option set to true
99 all pending which would have been started in the meantime are
100 skipped.
101
102 catch => 1
103 Catch any exception raised by a job. This is especially useful
104 in combination with the "nofork" option to avoid stopping the
105 main process when a job raises an exception (dies).
106
107 after_job => \&after_sub
108 Call a subroutine after a job has been run. The first argument
109 is the return value of the dispatched job, the reminding
110 arguments are the arguments with which the dispatched job has
111 been called.
112
113 Example:
114
115 my $cron = new Schedule::Cron(..., after_job => sub {
116 my ($ret,@args) = @_;
117 print "Return value: ",$ret," - job arguments: (",join ":",@args,")\n";
118 });
119
120 log => \&log_sub
121 Install a logging subroutine. The given subroutine is called
122 for several events during the lifetime of a job. This method is
123 called with two arguments: A log level of 0 (info),1 (warning)
124 or 2 (error) depending on the importance of the message and the
125 message itself.
126
127 For example, you could use Log4perl (<http://log4perl.sf.net>)
128 for logging purposes for example like in the following code
129 snippet:
130
131 use Log::Log4perl;
132 use Log::Log4perl::Level;
133
134 my $log_method = sub {
135 my ($level,$msg) = @_;
136 my $DBG_MAP = { 0 => $INFO, 1 => $WARN, 2 => $ERROR };
137
138 my $logger = Log::Log4perl->get_logger("My::Package");
139 $logger->log($DBG_MAP->{$level},$msg);
140 }
141
142 my $cron = new Schedule::Cron(.... , log => $log_method);
143
144 loglevel => <-1,0,1,2>
145 Restricts logging to the specified severity level or below.
146 Use 0 to have all messages generated, 1 for only warnings and
147 errors and 2 for errors only. Default is 0 (all messages). A
148 loglevel of -1 (debug) will include job argument lists (also in
149 $0) in the job start message logged with a level of 0 or above.
150 You may have security concerns with this. Unless you are
151 debugging, use 0 or higher. A value larger than 2 will disable
152 logging completely.
153
154 Although you can filter in your log routine, generating the
155 messages can be expensive, for example if you pass arguments
156 pointing to large hashes. Specifying a loglevel avoids
157 formatting data that your routine would discard.
158
159 processprefix => <name>
160 Cron::Schedule sets the process' name (i.e. $0) to contain some
161 informative messages like when the next job executes or with
162 which arguments a job is called. By default, the prefix for
163 this labels is "Schedule::Cron". With this option you can set
164 it to something different. You can e.g. use $0 to include the
165 original process name. You can inhibit this with the
166 "nostatus" option, and prevent the argument display by setting
167 "loglevel" to zero or higher.
168
169 sleep => \&hook
170 If specified, &hook will be called instead of sleep(), with the
171 time to sleep in seconds as first argument and the
172 Schedule::Cron object as second. This hook allows you to use
173 select() instead of sleep, so that you can handle IO, for
174 example job requests from a network connection.
175
176 e.g.
177
178 $cron->run( { sleep => \&sleep_hook, nofork => 1 } );
179
180 sub sleep_hook {
181 my ($time, $cron) = @_;
182
183 my ($rin, $win, $ein) = ('','','');
184 my ($rout, $wout, $eout);
185 vec($rin, fileno(STDIN), 1) = 1;
186 my ($nfound, $ttg) = select($rout=$rin, $wout=$win, $eout=$ein, $time);
187 if ($nfound) {
188 handle_io($rout, $wout, $eout);
189 }
190 return;
191 }
192
193 $cron->load_crontab($file)
194 $cron->load_crontab(file=>$file,[eval=>1])
195 Loads and parses the crontab file $file. The entries found in this
196 file will be added to the current time table with
197 "$cron->add_entry".
198
199 The format of the file consists of cron commands containing of
200 lines with at least 5 columns, whereas the first 5 columns specify
201 the date. The rest of the line (i.e columns 6 and greater)
202 contains the argument with which the dispatcher subroutine will be
203 called. By default, the dispatcher will be called with one single
204 string argument containing the rest of the line literally.
205 Alternatively, if you call this method with the optional argument
206 "eval=>1" (you must then use the second format shown above), the
207 rest of the line will be evaled before used as argument for the
208 dispatcher.
209
210 For the format of the first 5 columns, please see "add_entry".
211
212 Blank lines and lines starting with a "#" will be ignored.
213
214 There's no way to specify another subroutine within the crontab
215 file. All calls will be made to the dispatcher provided at
216 construction time.
217
218 If you want to start up fresh, you should
219 call "$cron->clean_timetable()" before.
220
221 Example of a crontab fiqw(le:)
222
223 # The following line runs on every Monday at 2:34 am
224 34 2 * * Mon "make_stats"
225 # The next line should be best read in with an eval=>1 argument
226 * * 1 1 * { NEW_YEAR => '1',HEADACHE => 'on' }
227
228 $cron->add_entry($timespec,[arguments])
229 Adds a new entry to the list of scheduled cron jobs.
230
231 Time and Date specification
232
233 $timespec is the specification of the scheduled time in crontab
234 format (crontab(5)) which contains five mandatory time and date
235 fields and an optional 6th column. $timespec can be either a plain
236 string, which contains a whitespace separated time and date
237 specification. Alternatively, $timespec can be a reference to an
238 array containing the five elements for the date fields.
239
240 The time and date fields are (taken mostly from crontab(5), "Vixie"
241 cron):
242
243 field values
244 ===== ======
245 minute 0-59
246 hour 0-23
247 day of month 1-31
248 month 1-12 (or as names)
249 day of week 0-7 (0 or 7 is Sunday, or as names)
250 seconds 0-59 (optional)
251
252 A field may be an asterisk (*), which always stands for
253 ``first-last''.
254
255 Ranges of numbers are allowed. Ranges are two numbers
256 separated with a hyphen. The specified range is
257 inclusive. For example, 8-11 for an ``hours'' entry
258 specifies execution at hours 8, 9, 10 and 11.
259
260 Lists are allowed. A list is a set of numbers (or
261 ranges) separated by commas. Examples: ``1,2,5,9'',
262 ``0-4,8-12''.
263
264 Step values can be used in conjunction with ranges.
265 Following a range with ``/<number>'' specifies skips of
266 the numbers value through the range. For example,
267 ``0-23/2'' can be used in the hours field to specify
268 command execution every other hour (the alternative in
269 the V7 standard is ``0,2,4,6,8,10,12,14,16,18,20,22'').
270 Steps are also permitted after an asterisk, so if you
271 want to say ``every two hours'', just use ``*/2''.
272
273 Names can also be used for the ``month'' and ``day of
274 week'' fields. Use the first three letters of the
275 particular day or month (case doesn't matter).
276
277 Note: The day of a command's execution can be specified
278 by two fields -- day of month, and day of week.
279 If both fields are restricted (ie, aren't *), the
280 command will be run when either field matches the
281 current time. For example, ``30 4 1,15 * 5''
282 would cause a command to be run at 4:30 am on the
283 1st and 15th of each month, plus every Friday
284
285 Examples:
286
287 "8 0 * * *" ==> 8 minutes after midnight, every day
288 "5 11 * * Sat,Sun" ==> at 11:05 on each Saturday and Sunday
289 "0-59/5 * * * *" ==> every five minutes
290 "42 12 3 Feb Sat" ==> at 12:42 on 3rd of February and on
291 each Saturday in February
292 "32 11 * * * 0-30/2" ==> 11:32:00, 11:32:02, ... 11:32:30 every
293 day
294
295 In addition, ranges or lists of names are allowed.
296
297 An optional sixth column can be used to specify the seconds within
298 the minute. If not present, it is implicitly set to "0".
299
300 Command specification
301
302 The subroutine to be executed when the the $timespec matches can be
303 specified in several ways.
304
305 First, if the optional "arguments" are lacking, the default
306 dispatching subroutine provided at construction time will be called
307 without arguments.
308
309 If the second parameter to this method is a reference to a
310 subroutine, this subroutine will be used instead of the dispatcher.
311
312 Any additional parameters will be given as arguments to the
313 subroutine to be executed. You can also specify a reference to an
314 array instead of a list of parameters.
315
316 You can also use a named parameter list provided as an hashref.
317 The named parameters recognized are:
318
319 subroutine
320 sub Reference to subroutine to be executed
321
322 arguments
323 args
324 Reference to array containing arguments to be use when calling
325 the subroutine
326
327 eval
328 If true, use the evaled string provided with the "arguments"
329 parameter. The evaluation will take place immediately (not
330 when the subroutine is going to be called)
331
332 Examples:
333
334 $cron->add_entry("* * * * *");
335 $cron->add_entry("* * * * *","doit");
336 $cron->add_entry("* * * * *",\&dispatch,"first",2,"third");
337 $cron->add_entry("* * * * *",{'subroutine' => \&dispatch,
338 'arguments' => [ "first",2,"third" ]});
339 $cron->add_entry("* * * * *",{'subroutine' => \&dispatch,
340 'arguments' => '[ "first",2,"third" ]',
341 'eval' => 1});
342
343 @entries = $cron->list_entries()
344 Return a list of cron entries. Each entry is a hash reference of
345 the following form:
346
347 $entry = {
348 time => $timespec,
349 dispatch => $dispatcher,
350 args => $args_ref
351 }
352
353 Here $timespec is the specified time in crontab format as provided
354 to "add_entry", $dispatcher is a reference to the dispatcher for
355 this entry and $args_ref is a reference to an array holding
356 additional arguments (which can be an empty array reference). For
357 further explanation of this arguments refer to the documentation of
358 the method "add_entry".
359
360 The order index of each entry can be used within "update_entry",
361 "get_entry" and "delete_entry". But be aware, when you are deleting
362 an entry, that you have to refetch the list, since the order will
363 have changed.
364
365 Note that these entries are returned by value and were opbtained
366 from the internal list by a deep copy. I.e. you are free to modify
367 it, but this won't influence the original entries. Instead use
368 "update_entry" if you need to modify an existing crontab entry.
369
370 $entry = $cron->get_entry($idx)
371 Get a single entry. $entry is either a hashref with the possible
372 keys "time", "dispatch" and "args" (see "list_entries()") or undef
373 if no entry with the given index $idx exists.
374
375 $cron->delete_entry($idx)
376 Delete the entry at index $idx. Returns the deleted entry on
377 success, "undef" otherwise.
378
379 $cron->update_entry($idx,$entry)
380 Updates the entry with index $idx. $entry is a hash ref as
381 described in "list_entries()" and must contain at least a value
382 "$entry->{time}". If no "$entry->{dispatcher}" is given, then the
383 default dispatcher is used. This method returns the old entry on
384 success, "undef" otherwise.
385
386 $cron->run([options])
387 This method starts the scheduler.
388
389 When called without options, this method will never return and
390 executes the scheduled subroutine calls as needed.
391
392 Alternatively, you can detach the main scheduler loop from the
393 current process (daemon mode). In this case, the pid of the forked
394 scheduler process will be returned.
395
396 The "options" parameter specifies the running mode of
397 "Schedule::Cron". It can be either a plain list which will be
398 interpreted as a hash or it can be a reference to a hash. The
399 following named parameters (keys of the provided hash) are
400 recognized:
401
402 detach
403 If set to a true value the scheduler process is detached from
404 the current process (UNIX only).
405
406 pid_file
407 If running in daemon mode, name the optional file, in which the
408 process id of the scheduler process should be written. By
409 default, no PID File will be created.
410
411 nofork, skip, catch, log, loglevel, nostatus, sleep
412 See "new()" for a description of these configuration
413 parameters, which can be provided here as well. Note, that the
414 options given here overrides those of the constructor.
415
416 Examples:
417
418 # Start scheduler, detach from current process and
419 # write the PID of the forked scheduler to the
420 # specified file
421 $cron->run(detach=>1,pid_file=>"/var/run/scheduler.pid");
422
423 # Start scheduler and wait forever.
424 $cron->run();
425
426 $cron->clean_timetable()
427 Remove all scheduled entries
428
429 $cron->check_entry($id)
430 Check, whether the given ID is already registered in the timetable.
431 A ID is the first argument in the argument parameter of the a
432 crontab entry.
433
434 Returns (one of) the index in the timetable (can be 0, too) if the
435 ID could be found or "undef" otherwise.
436
437 Example:
438
439 $cron->add_entry("* * * * *","ROTATE");
440 .
441 .
442 defined($cron->check_entry("ROTATE")) || die "No ROTATE entry !"
443
444 $cron->get_next_execution_time($cron_entry,[$ref_time])
445 Well, this is mostly an internal method, but it might be useful on
446 its own.
447
448 The purpose of this method is to calculate the next execution time
449 from a specified crontab entry
450
451 Parameters:
452
453 $cron_entry
454 The crontab entry as specified in "add_entry"
455
456 $ref_time
457 The reference time for which the next time should be searched
458 which matches $cron_entry. By default, take the current time
459
460 This method returns the number of epoch-seconds of the next matched
461 date for $cron_entry.
462
463 Since I suspect, that this calculation of the next execution time
464 might fail in some circumstances (bugs are lurking everywhere ;-)
465 an additional interactive method "bug()" is provided for checking
466 crontab entries against your expected output. Refer to the top-
467 level README for additional usage information for this method.
468
470 Daylight saving occurs typically twice a year: In the first switch, one
471 hour is skipped. Any job which which triggers in this skipped hour will
472 be fired in the next hour. So, when the DST switch goes from 2:00 to
473 3:00 a job which is scheduled for 2:43 will be executed at 3:43.
474
475 For the reverse backwards switch later in the year, the behaviour is
476 undefined. Two possible behaviours can occur: For jobs triggered in
477 short intervals, where the next execution time would fire in the extra
478 hour as well, the job could be executed again or skipped in this extra
479 hour. Currently, running "Schedule::Cron" in "MET" would skip the extra
480 job, in "PST8PDT" it would execute a second time. The reason is the way
481 how Time::ParseDate calculates epoch times for dates given like
482 "02:50:00 2009/10/25". Should it return the seconds since 1970 for this
483 time happening 'first', or for this time in the extra hour ? As it
484 turns out, Time::ParseDate returns the epoch time of the first
485 occurrence for "PST8PDT" and for "MET" it returns the second
486 occurrence. Unfortunately, there is no way to specify which entry
487 Time::ParseDate should pick (until now). Of course, after all, this is
488 obviously not Time::ParseDate's fault, since a simple date
489 specification within the DST backswitch period is ambiguous. However,
490 it would be nice if the parsing behaviour of Time::ParseDate would be
491 consistent across time zones (a ticket has be raised for fixing this).
492 Then Schedule::Cron's behaviour within a DST backward switch would be
493 consistent as well.
494
495 Since changing the internal algorithm which worked now for over ten
496 years would be too risky and I don't see any simple solution for this
497 right now, it is likely that this undefined behaviour will exist for
498 some time. Maybe some hero is coming along and will fix this, but this
499 is probably not me ;-)
500
501 Sorry for that.
502
504 Copyright 1999-2011 Roland Huss.
505
506 This library is free software; you can redistribute it and/or modify it
507 under the same terms as Perl itself.
508
510 ... roland
511
512
513
514perl v5.32.1 2021-01-27 Schedule::Cron(3)