1Schedule::Cron(3)     User Contributed Perl Documentation    Schedule::Cron(3)
2
3
4

NAME

6       Cron - cron-like scheduler for Perl subroutines
7

SYNOPSIS

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

DESCRIPTION

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

METHODS

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

DST ISSUES

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

LICENSE

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

AUTHOR

510       ... roland
511
512
513
514perl v5.30.1                      2020-01-30                 Schedule::Cron(3)
Impressum