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 processname => <name>
170 Set the process name (i.e. $0) to a literal string. Using this
171 setting overrides "processprefix" and "nostatus".
172
173 sleep => \&hook
174 If specified, &hook will be called instead of sleep(), with the
175 time to sleep in seconds as first argument and the
176 Schedule::Cron object as second. This hook allows you to use
177 select() instead of sleep, so that you can handle IO, for
178 example job requests from a network connection.
179
180 e.g.
181
182 $cron->run( { sleep => \&sleep_hook, nofork => 1 } );
183
184 sub sleep_hook {
185 my ($time, $cron) = @_;
186
187 my ($rin, $win, $ein) = ('','','');
188 my ($rout, $wout, $eout);
189 vec($rin, fileno(STDIN), 1) = 1;
190 my ($nfound, $ttg) = select($rout=$rin, $wout=$win, $eout=$ein, $time);
191 if ($nfound) {
192 handle_io($rout, $wout, $eout);
193 }
194 return;
195 }
196
197 $cron->load_crontab($file)
198 $cron->load_crontab(file=>$file,[eval=>1])
199 Loads and parses the crontab file $file. The entries found in this
200 file will be added to the current time table with
201 "$cron->add_entry".
202
203 The format of the file consists of cron commands containing of
204 lines with at least 5 columns, whereas the first 5 columns specify
205 the date. The rest of the line (i.e columns 6 and greater)
206 contains the argument with which the dispatcher subroutine will be
207 called. By default, the dispatcher will be called with one single
208 string argument containing the rest of the line literally.
209 Alternatively, if you call this method with the optional argument
210 "eval=>1" (you must then use the second format shown above), the
211 rest of the line will be evaled before used as argument for the
212 dispatcher.
213
214 For the format of the first 5 columns, please see "add_entry".
215
216 Blank lines and lines starting with a "#" will be ignored.
217
218 There's no way to specify another subroutine within the crontab
219 file. All calls will be made to the dispatcher provided at
220 construction time.
221
222 If you want to start up fresh, you should
223 call "$cron->clean_timetable()" before.
224
225 Example of a crontab fiqw(le:)
226
227 # The following line runs on every Monday at 2:34 am
228 34 2 * * Mon "make_stats"
229 # The next line should be best read in with an eval=>1 argument
230 * * 1 1 * { NEW_YEAR => '1',HEADACHE => 'on' }
231
232 $cron->add_entry($timespec,[arguments])
233 Adds a new entry to the list of scheduled cron jobs.
234
235 Time and Date specification
236
237 $timespec is the specification of the scheduled time in crontab
238 format (crontab(5)) which contains five mandatory time and date
239 fields and an optional 6th column. $timespec can be either a plain
240 string, which contains a whitespace separated time and date
241 specification. Alternatively, $timespec can be a reference to an
242 array containing the five elements for the date fields.
243
244 The time and date fields are (taken mostly from crontab(5), "Vixie"
245 cron):
246
247 field values
248 ===== ======
249 minute 0-59
250 hour 0-23
251 day of month 1-31
252 month 1-12 (or as names)
253 day of week 0-7 (0 or 7 is Sunday, or as names)
254 seconds 0-59 (optional)
255
256 A field may be an asterisk (*), which always stands for
257 ``first-last''.
258
259 Ranges of numbers are allowed. Ranges are two numbers
260 separated with a hyphen. The specified range is
261 inclusive. For example, 8-11 for an ``hours'' entry
262 specifies execution at hours 8, 9, 10 and 11.
263
264 Lists are allowed. A list is a set of numbers (or
265 ranges) separated by commas. Examples: ``1,2,5,9'',
266 ``0-4,8-12''.
267
268 Step values can be used in conjunction with ranges.
269 Following a range with ``/<number>'' specifies skips of
270 the numbers value through the range. For example,
271 ``0-23/2'' can be used in the hours field to specify
272 command execution every other hour (the alternative in
273 the V7 standard is ``0,2,4,6,8,10,12,14,16,18,20,22'').
274 Steps are also permitted after an asterisk, so if you
275 want to say ``every two hours'', just use ``*/2''.
276
277 Names can also be used for the ``month'' and ``day of
278 week'' fields. Use the first three letters of the
279 particular day or month (case doesn't matter).
280
281 Note: The day of a command's execution can be specified
282 by two fields -- day of month, and day of week.
283 If both fields are restricted (ie, aren't *), the
284 command will be run when either field matches the
285 current time. For example, ``30 4 1,15 * 5''
286 would cause a command to be run at 4:30 am on the
287 1st and 15th of each month, plus every Friday
288
289 Examples:
290
291 "8 0 * * *" ==> 8 minutes after midnight, every day
292 "5 11 * * Sat,Sun" ==> at 11:05 on each Saturday and Sunday
293 "0-59/5 * * * *" ==> every five minutes
294 "42 12 3 Feb Sat" ==> at 12:42 on 3rd of February and on
295 each Saturday in February
296 "32 11 * * * 0-30/2" ==> 11:32:00, 11:32:02, ... 11:32:30 every
297 day
298
299 In addition, ranges or lists of names are allowed.
300
301 An optional sixth column can be used to specify the seconds within
302 the minute. If not present, it is implicitly set to "0".
303
304 Command specification
305
306 The subroutine to be executed when the $timespec matches can be
307 specified in several ways.
308
309 First, if the optional "arguments" are lacking, the default
310 dispatching subroutine provided at construction time will be called
311 without arguments.
312
313 If the second parameter to this method is a reference to a
314 subroutine, this subroutine will be used instead of the dispatcher.
315
316 Any additional parameters will be given as arguments to the
317 subroutine to be executed. You can also specify a reference to an
318 array instead of a list of parameters.
319
320 You can also use a named parameter list provided as an hashref.
321 The named parameters recognized are:
322
323 subroutine
324 sub Reference to subroutine to be executed
325
326 arguments
327 args
328 Reference to array containing arguments to be use when calling
329 the subroutine
330
331 eval
332 If true, use the evaled string provided with the "arguments"
333 parameter. The evaluation will take place immediately (not
334 when the subroutine is going to be called)
335
336 Examples:
337
338 $cron->add_entry("* * * * *");
339 $cron->add_entry("* * * * *","doit");
340 $cron->add_entry("* * * * *",\&dispatch,"first",2,"third");
341 $cron->add_entry("* * * * *",{'subroutine' => \&dispatch,
342 'arguments' => [ "first",2,"third" ]});
343 $cron->add_entry("* * * * *",{'subroutine' => \&dispatch,
344 'arguments' => '[ "first",2,"third" ]',
345 'eval' => 1});
346
347 @entries = $cron->list_entries()
348 Return a list of cron entries. Each entry is a hash reference of
349 the following form:
350
351 $entry = {
352 time => $timespec,
353 dispatch => $dispatcher,
354 args => $args_ref
355 }
356
357 Here $timespec is the specified time in crontab format as provided
358 to "add_entry", $dispatcher is a reference to the dispatcher for
359 this entry and $args_ref is a reference to an array holding
360 additional arguments (which can be an empty array reference). For
361 further explanation of this arguments refer to the documentation of
362 the method "add_entry".
363
364 The order index of each entry can be used within "update_entry",
365 "get_entry" and "delete_entry". But be aware, when you are deleting
366 an entry, that you have to refetch the list, since the order will
367 have changed.
368
369 Note that these entries are returned by value and were obtained
370 from the internal list by a deep copy. I.e. you are free to modify
371 it, but this won't influence the original entries. Instead use
372 "update_entry" if you need to modify an existing crontab entry.
373
374 $entry = $cron->get_entry($idx)
375 Get a single entry. $entry is either a hashref with the possible
376 keys "time", "dispatch" and "args" (see list_entries()) or undef if
377 no entry with the given index $idx exists.
378
379 $cron->delete_entry($idx)
380 Delete the entry at index $idx. Returns the deleted entry on
381 success, "undef" otherwise.
382
383 $cron->update_entry($idx,$entry)
384 Updates the entry with index $idx. $entry is a hash ref as
385 described in list_entries() and must contain at least a value
386 "$entry->{time}". If no "$entry->{dispatcher}" is given, then the
387 default dispatcher is used. This method returns the old entry on
388 success, "undef" otherwise.
389
390 $cron->run([options])
391 This method starts the scheduler.
392
393 When called without options, this method will never return and
394 executes the scheduled subroutine calls as needed.
395
396 Alternatively, you can detach the main scheduler loop from the
397 current process (daemon mode). In this case, the pid of the forked
398 scheduler process will be returned.
399
400 The "options" parameter specifies the running mode of
401 "Schedule::Cron". It can be either a plain list which will be
402 interpreted as a hash or it can be a reference to a hash. The
403 following named parameters (keys of the provided hash) are
404 recognized:
405
406 detach
407 If set to a true value the scheduler process is detached from
408 the current process (UNIX only).
409
410 pid_file
411 If running in daemon mode, name the optional file, in which the
412 process id of the scheduler process should be written. By
413 default, no PID File will be created.
414
415 nofork, skip, catch, log, loglevel, nostatus, sleep
416 See new() for a description of these configuration parameters,
417 which can be provided here as well. Note, that the options
418 given here overrides those of the constructor.
419
420 Examples:
421
422 # Start scheduler, detach from current process and
423 # write the PID of the forked scheduler to the
424 # specified file
425 $cron->run(detach=>1,pid_file=>"/var/run/scheduler.pid");
426
427 # Start scheduler and wait forever.
428 $cron->run();
429
430 $cron->clean_timetable()
431 Remove all scheduled entries
432
433 $cron->check_entry($id)
434 Check, whether the given ID is already registered in the timetable.
435 A ID is the first argument in the argument parameter of the a
436 crontab entry.
437
438 Returns (one of) the index in the timetable (can be 0, too) if the
439 ID could be found or "undef" otherwise.
440
441 Example:
442
443 $cron->add_entry("* * * * *","ROTATE");
444 .
445 .
446 defined($cron->check_entry("ROTATE")) || die "No ROTATE entry !"
447
448 $cron->get_next_execution_time($cron_entry,[$ref_time])
449 Well, this is mostly an internal method, but it might be useful on
450 its own.
451
452 The purpose of this method is to calculate the next execution time
453 from a specified crontab entry
454
455 Parameters:
456
457 $cron_entry
458 The crontab entry as specified in "add_entry"
459
460 $ref_time
461 The reference time for which the next time should be searched
462 which matches $cron_entry. By default, take the current time
463
464 This method returns the number of epoch-seconds of the next matched
465 date for $cron_entry.
466
467 Since I suspect, that this calculation of the next execution time
468 might fail in some circumstances (bugs are lurking everywhere ;-)
469 an additional interactive method bug() is provided for checking
470 crontab entries against your expected output. Refer to the top-
471 level README for additional usage information for this method.
472
473 $cron->set_timeshift($ts)
474 Modify global time shift for all timetable. The timeshift is subbed
475 from localtime to calculate next execution time for all scheduled
476 jobs.
477
478 ts parameter must be in seconds. Default value is 0. Negative
479 values are allowed to shift time in the past.
480
481 Returns actual timeshift in seconds.
482
483 Example:
484
485 $cron->set_timeshift(120);
486
487 Will delay all jobs 2 minutes in the future.
488
490 Daylight saving occurs typically twice a year: In the first switch, one
491 hour is skipped. Any job which triggers in this skipped hour will be
492 fired in the next hour. So, when the DST switch goes from 2:00 to 3:00
493 a job which is scheduled for 2:43 will be executed at 3:43.
494
495 For the reverse backwards switch later in the year, the behaviour is
496 undefined. Two possible behaviours can occur: For jobs triggered in
497 short intervals, where the next execution time would fire in the extra
498 hour as well, the job could be executed again or skipped in this extra
499 hour. Currently, running "Schedule::Cron" in "MET" would skip the extra
500 job, in "PST8PDT" it would execute a second time. The reason is the way
501 how Time::ParseDate calculates epoch times for dates given like
502 "02:50:00 2009/10/25". Should it return the seconds since 1970 for this
503 time happening 'first', or for this time in the extra hour ? As it
504 turns out, Time::ParseDate returns the epoch time of the first
505 occurrence for "PST8PDT" and for "MET" it returns the second
506 occurrence. Unfortunately, there is no way to specify which entry
507 Time::ParseDate should pick (until now). Of course, after all, this is
508 obviously not Time::ParseDate's fault, since a simple date
509 specification within the DST backswitch period is ambiguous. However,
510 it would be nice if the parsing behaviour of Time::ParseDate would be
511 consistent across time zones (a ticket has be raised for fixing this).
512 Then Schedule::Cron's behaviour within a DST backward switch would be
513 consistent as well.
514
515 Since changing the internal algorithm which worked now for over ten
516 years would be too risky and I don't see any simple solution for this
517 right now, it is likely that this undefined behaviour will exist for
518 some time. Maybe some hero is coming along and will fix this, but this
519 is probably not me ;-)
520
521 Sorry for that.
522
524 Roland Huß <roland@consol.de>
525
526 Currently maintained by Nicholas Hubbard <nicholashubbard@posteo.net>
527
529 • Alexandr Ciornii <alexchorny@gmail.com>
530
531 • Andrew Danforth
532
533 • Andy Ford
534
535 • Bray Jones
536
537 • Clinton Gormley
538
539 • Eric Wilhelm
540
541 • Frank Mayer
542
543 • Jamie McCarthy
544
545 • Loic Paillotin
546
547 • Nicholas Hubbard <nicholashubbard@posteo.net>
548
549 • Peter Vary
550
551 • Philippe Verdret
552
554 Copyright (c) 1999-2013 Roland Huß.
555
556 Copyright (c) 2022 Nicholas Hubbard.
557
558 This library is free software; you can redistribute it and/or modify it
559 under the same terms as Perl itself.
560
562 Hey! The above document had some coding errors, which are explained
563 below:
564
565 Around line 1916:
566 Non-ASCII character seen before =encoding in 'Huß'. Assuming UTF-8
567
568
569
570perl v5.36.0 2023-01-20 Schedule::Cron(3)