[Omaha.pm] Alarms in Perl.

Daniel Linder dan at linder.org
Thu Oct 25 09:08:16 PDT 2007


[No, it's DeJaVu, I accidentally posted this to the Omaha Local Users
Group instead of PM when I meant to post it here.  Sorry if you get this
twice. --Dan]

I have a handful of scripts that are run periodically 24x7.  Nearly all
the time, they run fine and report their status back when they exit
correctly.  On the odd occasion (about once every 1-2 weeks), a script
will hang at some point in the code and never exit - most likely a call to
an external program that didn't complete or hung itself.  (The reason for
the hanging is not the point of this e-mail.)

What I would like to setup is a simple alarm based action that would exit
the script -- no matter what -- if it was still running after an extended
period of time.  (I.e. if a script that should only take ten seconds to
run has been running for five minutes, exit with a value of 99.)

>From perl.com I found this code:
URL:http://www.perl.com/pub/a/2007/06/07/better-code-through-destruction.html?page=2
Code:
1:    eval{
2:        local $SIG{ALRM} = sub { die "Timed out\n" };
3:        alarm(5);
4:        my $sentry = Object::Destroyer->new( sub {alarm(0)} );
5:        long_running_code();
6:    };

Dissection:
Line 1: Wrapper the whole thing in an "eval" to make the "my $sentry" work.
Line 2: Setup what to do when the alarm triggers.
Line 3: Set the alarm to go off in 5 seconds.
Line 4: Setup a new variable that only exists within the "eval" block.
When the eval block exits, the $sentry variable object invokes the
Destroyer function.  (In this case it resets the alarm to 0, effectively
resetting the alarm on a good exit of the eval block.)
Line 5: Run the (possibly bad) code.  If it runs to completion within the
allotted time, the eval block exits, the alarm is reset, and the die never
gets called.  If the code takes too long, the die *is* called and the
whole script exits.

Questions:
1: Will (should) this work even if the "long_running_code()" uses system()
and or back-ticks to call out to external programs?  (I realize those
programs could be left running - I'm ok with having the admin clean them
up once they are alerted to the code not returning at all...)

2: Are the alarm() and Object::Destroyer calls part of the base Perl
modules, or will I be visiting CPAN to get this working?  (How do I check
what's included out of the box vs. what has been installed over time?)

3: Is there any command-line magic that perl can be invoked with that will
cause Perl to call a specific function if it is left running for a long
period of time?  (i.e. perl --timeout 300 --timeout-sub
'MyExitSubroutine()' ./MyBigPerlScript.pl)

Thanks,

Dan

- - - -
"There are four boxes to be used in defense of liberty: soap, ballot,
jury, and ammo. Please use in that order."
-- Ed Howdershelt (Author)

"I do not fear computers, I fear the lack of them." -- Isaac Asimov (Author)
** *** ***** ******* *********** *************
NRL, Shayet-13, NCCS, IRS, Reno, gorilla, anarchy
package, domestic disruption, UDT, Tie-fighter, Menwith, Masuda, c
Duress, Bubba the Love Sponge, HIC, BATF, package, TELINT, HPCC




More information about the Omaha-pm mailing list