in reply to Re: Ignoring/Trapping the DIE signal
in thread Ignoring/Trapping the DIE signal

Looks interesting, I'll give it a try...

Replies are listed 'Best First'.
Re^3: Ignoring/Trapping the DIE signal
by chrism01 (Friar) on Jun 15, 2006 at 05:42 UTC
    Maybe you could clarify that technique a bit. I tried:
    use Tie::Constrained; # Other code as before, with and without SIG{__DIE__} sub db_connect { my ( $dsn, # data source name $error_msg # if any ); # Set up connection string... $dsn = "DBI:mysql:database=xxx;host=somehost;port=nn"; tie $cfg::dbh, 'Tie::Constrained' => { test => sub { $_[0]->isa('DBI::db') and $_[0]->ping; }, value => DBI->connect($dsn, "user", "passwd", #'DBI:mysql:','','', {RaiseError => 0, AutoCommit => 1}), fail => sub { $_[1] = DBI->connect($dsn, "user", "passwd", {RaiseError => 0, AutoCommit => 1}); if( $DBI::errstr) { # FAIL $error_msg = "db_connect(): $DBI::errs +tr"; print "$error_msg\n"; $cfg::db_retry_cnt++; if( !$cfg::db_cxn_msg_sent && $cfg::db_retry_cnt > 3 ) { print "would have sent email/sms\n +"; $cfg::db_cxn_msg_sent = 1; } } else { # SUCCESS $cfg::db_cxn_msg_sent = 0; $cfg::db_retry_cnt = 0; } } }; $Tie::Constrained::STRICT = 1; }
    Didn't quite understand the DB def for 'value' being empty in example, but tried it anyway, got 'DBD::mysql::st execute failed: No database selected' at each execute, so tried filling in with real values as above, and got same errors as in orig post, ending with 'Can't call method "quote" on an undefined value at ./pd.pl line 83', then perl died.
      I almost missed this, because you replied to your own node :)

      Anyway, I just went digging through my old code to find an example of what I'd used. Basically, I used a very simplified version of the above - something like this:

      sub check_db_connection { return 0 if $db->ping; for my $try (1 .. 3) { sleep 15; Log(*LOGFILE, "WARNING:: $0::db appears to have gone away, att +empting to reconnect (try $try)"); return 0 if $db = connectdb('mydatabase'); } Log(*LOGFILE, "ERROR: $0:Cannot reconnect to mydatabase, exiting." +); close(*LOGFILE); exit 0; }

      Then what I did was call check_db_connection before each database transaction.

      Is this the best way to do it? (I doubt it)
      Are there potential traps with the above? (Probably)

      But.... it worked fine for me for several months :)

      Cheers,
      Darren :)

        Yeah, that looks feasible in general, but as I mentioned in my OP, I don't want it to exit/die ever.
        (Thx for looking that up for me anyway)
        All the variations I've tried so far enable you to trap an error and do some(!) extra processing, then die/exit.
        The prob I'm getting is that if you want to continue anyway, which I do, it's pretty consistent (see my results) that after approx 3 DB related errors, Perl dies regardless, even if you use a SIG{__DIE_} trap! :-(
        If you know how to do what I want, I'll owe you big time...
        Don't suppose you know how I could get someone like Merlyn or some other Perl internals guy to look at this? I feel it ought to be possible.
        As background, the system is setup such that MySQL will (eventually) re-start, but I want my progs to survive till then, not die/restart as well.