Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
Do you know where your variables are?
 
PerlMonks  

$@ alternative

by Gangabass (Priest)
on Sep 10, 2007 at 05:29 UTC ( #637996=perlquestion: print w/ replies, xml ) Need Help??
Gangabass has asked for the wisdom of the Perl Monks concerning the following question:

Customer ask me to write DBI script which will change server if current server did't response. I write this simple code:

my $timeout = 10; #10 seconds timeout foreach my $source (@sources) { my dbh = connect_to_db($source); my sth = $dbh->prepare(YOU_QUERY_GOES_HERE); eval { local $SIG{ALRM} = sub {die "alarmn";}; alarm($timeout); $sth->execute(YOUR_PARAMS); alarm(0); }; unless ($@) { last; #ALL OK } else { #didnt print "Timeout happens!n"; } }

But customer said that he already use $@ in your script (and he can use it only once) so i need to rewrite my sample without using $@. How i can do this? May be there is some way to declare local copy of $@ and after my block to restore original value?

Comment on $@ alternative
Download Code
Re: $@ alternative
by runrig (Abbot) on Sep 10, 2007 at 05:33 UTC
    Why is he using $@? If he's not using it for an eval error, can't he use something else?

      I don't know :-(. And he did't answer. Can i add

      { local $@; ...my code goes here... }

      to preserve $@?

        $@ is global, so yes you can localize it, (and in general you should make a local copy if you want to preserve a previous exception).

        $@ being global, at the first exception triggered the previous contents of $@ will be destoyed, so that means probably your customer never used exception-eval blocks, or was just lucky, as the following code demonstrates.

        % steph@ape (/home/stephan/r) % % perl -we '$@ = "customer stuff..."; eval { die "dont muck with $@!" +}; print $@' dont muck with ! at -e line 1. % steph@ape (/home/stephan/r) % % perl -we '$@ = "customer stuff..."; { local $@; eval { die "dont muc +k with $@!" }; } print $@' customer stuff...
        cheers --stephan
Re: $@ alternative
by rdfield (Priest) on Sep 10, 2007 at 11:47 UTC
    You could use your own global variable which is set to a non-zero value when the alarm is triggered.

    rdfield

Re: $@ alternative
by kyle (Abbot) on Sep 10, 2007 at 12:14 UTC

    This might work:

    my $timeout = 10; # 10 seconds timeout SOURCE: foreach my $source (@sources) { my dbh = connect_to_db($source); my sth = $dbh->prepare( $your_query ); my $eval_result = eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm( $timeout ); $sth->execute( $your_params ); alarm( 0 ); 1; }; if ( $eval_result ) { last SOURCE; # ALL OK } else { print "Timeout happens!\n"; } }

    It might be useful to see also How to timeout if a call to an external program takes too long and Re: Question on "Effective Perl Programming" (;1 > $@).

    Note that the above will actually change $@ when it's run, even though it doesn't use it otherwise. If you really want code that doesn't touch $@, using local is the way to go.

      $@ will still be changed. ( Oops, the parent already said that. )
Re: $@ alternative
by samtregar (Abbot) on Sep 10, 2007 at 21:46 UTC
    Not what you asked about, but I thought I should point out that your code may cause hard to trace memory corruption. Your DBD driver is likely XS code linking to a compiled client library, most are. Interupting code like that with a signal and then trying to call back into that code will work most of the time, until it doesn't. When it doesn't you'll get very bizarre results - crashes in unrelated areas of code for example. The reason is that your DBD driver may be keeping global state which is left in an inconsistent state by your alarm interupt.

    I wrote DBIx::Timeout to deal with this problem. It only works for MySQL at the moment but I believe the concept should be portable.

    -sam

      Thanks! I'll take a look to it.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://637996]
Approved by planetscape
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (9)
As of 2014-04-16 11:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (424 votes), past polls