in reply to die through several evals
This problem case is exactly why the common best practice (especially outside of Perl) is throwing structured exceptions and catching only the failures that the particular block of code is prepared to deal with.
But implementing structured exceptions and 'catch' for all of the 'eval' blocks involved in your case may be a lot to bite off in order to solve your timeout problem.
It doesn't help that there isn't an accepted, great structured exception implementation on CPAN. We recently rolled our own based on the fairly simple and good ideas included in Error::Exception with several additional best practices I've collected from a few prior groups I've worked with: default values for attributes, required attributes, reuse modeled more on tags than on inheritance, "private" attributes and "private" exceptions that don't get shown to end users (just go to the log), don't create a separate Perl class for each exception type.
A simple way to get past multiple eval blocks is to update each to know to rethrow the timeout:
... $SIG{ALRM} = sub { die 'timeout' }; ... do_work(); sub do_work { ... eval { ... } ... die $@ if 'timeout' eq $@; ... }
I worry that this is rather hackish, but you can use something like the following, and not update any of your eval blocks:
my $timed_out = 1; TIMEOUT_BLOCK_WITH_UNIQUE_LABEL: { local $SIG{ALRM} = sub { last TIMEOUT_BLOCK_WITH_UNIQUE_LABEL; }; my $err; eval { alarm( $seconds ); do_work(); 1 } or do { $err = $@ || 'Unknown error'; } alarm( 0 ); die $err if $err; $timed_out = 0; }
But at least it is a lot less worrisome to me than either Scope::Upper or Continuation::Escape.
- tye
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: die through several evals (last)
by kennethk (Abbot) on Apr 23, 2013 at 17:49 UTC | |
by tye (Sage) on Apr 23, 2013 at 20:12 UTC | |
by nyaapa (Novice) on Apr 24, 2013 at 09:27 UTC | |
|
Re^2: die through several evals (last)
by nyaapa (Novice) on Apr 24, 2013 at 09:39 UTC |