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

The standard technique for timing-out long-running procedures in Perl is something like this:

{ local $SIG{ ALRM } = sub { die 'timeout' }; alarm( MAX_SECONDS ); eval { molasses_in_january(); alarm( 0 ); }; if ( $@ ) { die if $@ !~ /timeout/; handle_timeout(); } }

(The Perl Cookbook, q.v., gives a slightly more elaborate technique featuring a second eval inside the first one, but the basic idea is the same.)

One serious problem with this technique is that it requires that the code running in the dynamic scope inside the eval does not itself use an eval, or, if it does, that it faithfully propagates our timeout error. These are very shaky assumptions...

In fact, I find myself now using a library written (badly) by someone else, and I'm finding that I can't safely timeout a certain long-running procedure because somewhere deep into the called code there's an eval that looks something like this

$cowbell = eval { more_cowbell() }; # eval errors blithely ignored ... # in some other code, far, far away die 'i got a fever' unless $cowbell;

This means that the code after my eval cannot distinguish between a timeout and some other error that may have happened...

And to make matters worse, due to the widespread uses of careless eval's like this one, I don't even know exactly which one of all of them is ultimately responsible for trapping and ignoring my ALRM signal. (My rendition of the problematic code radically simplifies the problem; in reality the relationship between the variables initialized as results of rogue eval's and the test that ultimately triggers the die statement is far more baroque and unclear than what I'm showing.)

I suppose that I could time the operation and use the measured elapsed time as a heuristic to decide whether the uninformative error message corresponds to a "real" error or to a disguised time-out error. But this is a very crude workaround.

Is there something better?

Also, any trick that may help spot which of all the evals in the alien code is responsible for this particular mess would be appreciated.


the lowliest monk