http://www.perlmonks.org?node_id=568886

jimbus has asked for the wisdom of the Perl Monks concerning the following question:

Greeting,

I've got a Perl script that runs via cron every 15 minutes and it does this pretty happily. I need to make some changes so that the system is more self-recovering in the event of a network outage or something that prevents the reporting system from getting the files it needs to process. The problem is I'm concerned that it could easily end up running longer than its window when trying to recover and ended up with multiple instances competing.

I'd like to get some input on how to manage this... Should I have a fixed time for the script to execute? Should the next instance tell the previous to clean up and exit gracefully? Should I let the first one finish its natural course and cancel new ones until it is done?

My vision is to have each instance do what it can to catch things up and exit before/as the next one starts, but I'm not sure how best to go about that.

Thanks,


--Jimbus aka Jim Babcock
Wireless Data Engineer and Geek Wannabe
jim-dot-babcock-at-usa-dot-com

Replies are listed 'Best First'.
Re: Of cron job management
by friedo (Prior) on Aug 22, 2006 at 16:01 UTC
    To prevent collisions, you can have the cronjob store its PID in a temp file, then, on the next invocation, check if the temp file exists, read it into $pid and kill 0, $pid. That will tell you if the old process is still alive, in which case you can exit or sleep for a while.
      In fact, File::Pid is used for just this.
Re: Of cron job management
by madbombX (Hermit) on Aug 22, 2006 at 16:22 UTC
    I would have to agree with [id://friedo]. The method that I use when running scripts via cron is when the script starts I create a pid file. Since I use Debian or Ubuntu everywhere, the state directory is /var/run. Therefore, I usually do the following:

    # Check if the program is running or died unexpectedly if (-e $PIDFile) { print "Error: $0 is still running."; # Here you can gracefully remove the process or just kill # it using a SIGNAL or kill this process and let the # original one run } else { open (PID, '>',$PIDFile); print PID $$; close (PID); }

    I personally would have the process run over and over until it can reach the network. If it can't reach the network, it logs the fact that it tried and then exits.

    Eric

Re: Of cron job management
by andyford (Curate) on Aug 22, 2006 at 16:48 UTC
    I've been using Schedule::Cron for many years. It will run as a daemon, spawn your jobs like cron and it has some options that might help you with your specific requirements:
    • nofork => 1
      Don't fork when starting the scheduler. Instead, the jobs are executed within current process.
    • skip => 1
      Skip any pending jobs whose time has passed. This option is only useful in combination with nofork where a job might block the execution of the following jobs for quite some time. By default, any pending job is executed even if its scheduled execution time has already passed. With this option set to true all pending which would have been started in the meantime are skipped.
    The module also has a built-in pidfile generating mechanism.

    andyford
    or non-Perl: Andy Ford

Re: Of cron job management
by shmem (Chancellor) on Aug 22, 2006 at 21:38 UTC
    Well, if I was a script and there'd be no work from my precessor be wasted, and in-timeness (how'd you say that?) is of concern, and I could go ahead where my precessor leaped off, I'd tell the previous instance to let go. Otherwise I'd just slink away.

    One point of interest - since the DATA filehandle points to the script which contains it, scripts can flock it and advertise later instances that there might be a running instance, as described here. Of course it's prudent to check if an instance is really running.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Of cron job management
by blahblahblah (Priest) on Aug 28, 2006 at 18:57 UTC