Job Scheduling

Perhaps the biggest problems with cron are that, in order to manage it, you have to do it one system at a time, and interactively.  PIKT offers a centrally directed, convenient-to-use, and options-rich alternative job scheduler.

Suppose you have a special security-related program or script, "watchdog.py", that you wish to run from time to time on all systems.  You might configure the job scheduling in the piktmaster's alerts.cfg file this way:

Watchdog

timing          15 0-23/4 * * *

execcmd         "/usr/local/bin/watchdog.py"
You would schedule this script on all systems using the command:
# piktc -ierv +S Watchdog +H all        [or: ... -H down sick]
This would install (due to the piktc 'i' option) a short Watchdog.alt script on the slave systems:
Watchdog
        exec "/usr/local/bin/watchdog.py"
add this line to the slave systems' piktd.conf (the piktc 'e', "enable", option):
15 0-23/4 * * * /pikt/bin/pikt +S Watchdog
and restart the piktd daemon (the 'r' option; 'v' says to be verbose).

This would have the slave system piktd run the Watchdog script, hence the watchdog.py program, every four hours at 15 minutes after the hour, much as cron would.  Like cron, PIKT would log the script run, in PIKT's case in the piktd.log:

May  6 11:56:00 ottawa piktd[1619]: [ID 1 INFO] /pikt/bin/pikt +S Watchdog
Suppose you need to run watchdog.py more often on some systems, less often on others.  Under extraordinary circumstances, suppose you want to run watchdog.py hourly.  You might specify this:
Watchdog

#ifdef paranoid
timing          15 * * * *
#elsedef
#  if missioncritical
timing          15 0-23/2 * * *
#  else
timing          15 0-23/4 * * *
#  endif
#endifdef

execcmd         "/usr/local/bin/watchdog.py"
If we are in so-called "paranoid" mode, we have piktd run watchdog.py on all systems 15 minutes after every hour.  Otherwise (in normal security mode), run it at 15 minutes after the hour every two hours on mission-critical systems, and 15 minutes after the hour every four hours only on all other systems.

Given watchdog.py's security function, one problem with these schedulings could be their predictability--in all cases, at 15 minutes after the hour.  What if we want to add some unpredictability to the scheduling?  We might do this:

timing          15 0-23/4 * * *
drift           10
which is equivalent to this (adding drift as a sixth field):
timing          15 * * * * 10
This tells piktd to run watchdog.py at 15 minutes after every hour give or take 10 minutes--that is, randomly as early as 5 minutes after the hour to as late as 25 minutes after the hour.

Or we might add unpredictability this way:

timing          15 50% * * *
This tells piktd to run watchdog.py 15 minutes after the hour with just a 50% chance for any particular hour--that is, on average every two hours.  We could also add drift to the mix:
timing          15 50% * * * 10
This directs piktd to run the script anywhere from 5 to 25 minutes after the hour, on average every two hours.  Note that, depending on luck, the script might run (with a random 20-minute drift) hour after hour without break, then not run at all until hours later when the luck changes.

Suppose we want to run this script (conditionally, with drift) at (un)certain times during the day, at other times during the night, and at still other times during the weekend.  We might do:

timing          15 6-21      * * 1-5 10  // mon-fri,  day  hrs
                15 6-21/2    * * 0,6 10  // sun,sat,  day  hrs
                15 0-5,22-23 * * *   20  // each day, nite hrs
These lines would appear in piktd.conf:
15 6-21 * * 1-5 10 /pikt/bin/pikt +S Watchdog
15 6-21/2 * * 0,6 10 /pikt/bin/pikt +S Watchdog
15 0-5,22-23 * * * 20 /pikt/bin/pikt +S Watchdog
Suppose watchdog.py calls for optional human (sysadmin) intervention, but it's a holiday weekend, and we are lightly staffed.  We might run the script less frequently on holiday weekends with this:
#ifndef holiday
timing          15 6-21      * * 1-5 10  // mon-fri,  day  hrs
                15 6-21/2    * * 0,6 10  // sun,sat,  day  hrs
                15 0-5,22-23 * * *   20  // each day, nite hrs
#elsedef
timing          15 6,18      * * *   10  // holiday, at 6 am and 6 pm
#endifdef
(We would have other vital scripts and alerts run unchanged, whether a holiday or not.)

What if we need to debug the watchdog.py script and have it specially run more often in test mode?  We might do this:

#ifndef test
#  ifndef holiday
timing          15 6-21      * * 1-5 10  // mon-fri,  day  hrs
                15 6-21/2    * * 0,6 10  // sun,sat,  day  hrs
                15 0-5,22-23 * * *   20  // each day, nite hrs
#  elsedef
timing          15 6,18      * * *   10  // holiday, at 6 am and 6 pm
#  endifdef
#elsedef
timing          0,15,30,45 * * * * // testing, every 15 mins, no drift
#endifdef
As another example, and admittedly a very complex (and artificial) one, now add per-machine differences back into the mix:
Watchdog

#ifndef test
#  ifndef holiday
#    if missioncritical
timing          15 6-21      * * 1-5 10  // mon-fri,  day  hrs
                15 6-21/2    * * 0,6 10  // sun,sat,  day  hrs
                15 0-5,22-23 * * *   20  // each day, nite hrs
#    else
timing          15 6-21/3    * * 1-5 10  // mon-fri,  day  hrs
                15 6-21/6    * * 0,6 10  // sun,sat,  day  hrs
#    endif
#  elsedef
#    if missioncritical
timing          15 6-21      * * 1-5 10  // mon-fri,  day  hrs
                15 6-21/2    * * 0,6 10  // sun,sat,  day  hrs
                15 0-5,22-23 * * *   20  // each day, nite hrs
#    else
timing          15 6,18 * * *  10  // holiday,  at 6 am and 6 pm
#    endif
#  endifdef
#elsedef
timing          0,15,30,45 * * * * // testing, every 15 mins, no drift
#endifdef

nice            10

execcmd         "/usr/local/bin/watchdog.py"
Several things to note:  For the mission-critical systems, they run watchdog.py under the same schedule, holiday or not.  If it's not a holiday, and for the non mission-critical systems, we don't run watchdog.py at night.  Testing mode runs according to the same predictable schedule (is unaffected by the system, the time of day, the day of the year, etc.).  And notice that we have told Unix/Linux to "nice" the watchdog.py run.  (That is, give it a higher or lower priority.  Needless to say, we can apply all sorts of #if and #ifdef logic to the 'nice' statement as well.)

Whew!  Is this potentially complicated or what?  And the complexities don't end here.  You could add to the mix, for example, PIKT process #include's and other advanced preprocessor directives (e.g., #set, #setenv, #echo).  You could also wrap a Pikt script around watchdog.py (say, RunWatchDog) and employ the full array of Pikt functions (e.g., #hour(), #day(), #weekday(), etc.) and programming logic to precisely control its execution.

Of course, if you don't need all this sophisticated complexity, keep it simple.  (Review the very first bare-bones timing example above.)  On the other hand (mode, system, day of the week, ...), if you want to fine-tune your job scheduling, PIKT gives you the power to do that.

Since PIKT is very flexible with its layout, you can add extra spaces, indentations, blank lines, comments--whatever you need to make your complicated specifications visually clearer.

You could also hide away some of the complexity using PIKT macros and #include files, for example:

Watchdog

#ifndef test  // we're not testing

#    ifndef holiday  // it's not a holiday

#        if missioncritical
#            include <alerts/watchdog_missioncritical_timings_alerts.cfg>
#        else
#            include <alerts/watchdog_timings_alerts.cfg>
#        endif

#    elsedef         // it is a holiday

#        if missioncritical
#            include <alerts/watchdog_missioncritical_timings_alerts.cfg>
#        else
timing          =watchdog_timings_holiday
#        endif

#    endifdef        // holiday

#elsedef      // we're testing

timing          =timings_test_every_15_minutes

#endifdef     // test

nice            =watchdog_nice

execcmd         =watchdog
We won't show you the #include file contents or the macro definitions.  Just use your imagination.

It bears repeating:  With PIKT, with job scheduling as with everything else, be as complicated as you like, or keep things simple.  You have the utmost power and flexibility.  All choices are entirely yours.

All complexity aside, let's not overlook:  You manage all of this complexity in a single configuration file (alerts.cfg) on a single machine (the piktmaster).  As complicated as you might make your central PIKT configuration, you no longer have to be bewildered by the vast array of crontab files, with all their many differences (some intended, in many cases not) scattered hither and yon across all of your many systems.

Equally important, you can reconfigure and reschedule across dozens or hundreds of systems with just a few quick edits and a piktc command or two.  (When you change a timing specification in alerts.cfg, you need to register that change with a 'piktc -er' command.)  You no longer have to spend hours and hours on job scheduling, logging into systems to edit the crontab (and perhaps restart the crond) one file and one system at a time.  Hooray!

prev page 1st page next page
 
Home | FAQ | News | Intro | Samples | Tutorial | Reference | Software
Developer's Notes | Licensing | Authors | Pikt-Users | Pikt-Workers | Related Projects | Site Index | Privacy Policy | Contact Us
Page best viewed at 1024x768 or greater.   Page last updated 2019-01-12.   This site is PIKT® powered.
Copyright © 1998-2019 Robert Osterlund. All rights reserved.
Home FAQ News Intro Samples Tutorial Reference Software
PIKT Logo
PIKT Page Title
View sample
script scheduling
macros