[LA.pm] Apache::DBI pings

Kevin Scaldeferri kevin+lapm at scaldeferri.com
Mon May 16 15:24:18 PDT 2005


I was reading through Apache::DBI... you know, for fun... and there was 
something about this snippet that confused me:

     # do we need to ping the database ?
     $PingTimeOut{$dsn}  = 0 unless $PingTimeOut{$dsn};
     $LastPingTime{$dsn} = 0 unless $LastPingTime{$dsn};
     my $now = time;
     my $needping = (($PingTimeOut{$dsn} == 0 or $PingTimeOut{$dsn} > 0) 
and $now - $LastPingTime{$dsn} > $PingTimeOut{$dsn}) ? 1 : 0;
     print STDERR "$prefix need ping: ", $needping == 1 ? "yes" : "no", 
"\n" if $Apache::DBI::DEBUG > 1;
     $LastPingTime{$dsn} = $now;

     # check first if there is already a database-handle cached
     # if this is the case, possibly verify the database-handle
     # using the ping-method. Use eval for checking the connection
     # handle in order to avoid problems (dying inside ping) when
     # RaiseError being on and the handle is invalid.
     if ($Connected{$Idx} and (!$needping or 
eval{$Connected{$Idx}->ping})) {
         print STDERR "$prefix already connected to '$Idx'\n" if 
$Apache::DBI::DEBUG > 1;
         return (bless $Connected{$Idx}, 'Apache::DBI::db');
     }


I had always assumed that the ping happened every N seconds, but I came 
to realize that it's only if it's been more than N seconds since the 
last query.  Of course, it turns out it's actually documented that that 
is the case:

> This configures the usage of the ping method, to validate a 
> connection. Setting the timeout to 0 will always validate the database 
> connection using the ping method (default). Setting the timeout < 0 
> will de-activate the validation of the database handle. This can be 
> used for drivers, which do not implement the ping-method. Setting the 
> timeout > 0 will ping the database only if the last access was more 
> than timeout seconds before.


If we assume that the only reason a database connection ever goes bad 
is because the server times it out from inactivity, this all works 
fine.  And, if you take the default ping time of 0, it's all good 
because you always ping, and always restore a dead connection.  But, I 
get confused about what happens if you set the ping interval > 0 and 
greater than your query frequency, and the connection drops for some 
other reason.  Won't you never ping (because you're querying too 
frequently), and never automatically reconnect?  Presumably your 
application will scream bloody murder when you try to do things like 
prepare and execute statements, but it's not clear to me how you would 
recover from the problem, without killing off the child process.

Perhaps I'm just being stupid today.  The "mod_perl Developer's 
Cookbook" does assert in passing that Apache::DBI is robust against 
catastrophic connection failures, but I'm having a hard time seeing it 
in the code.


Thanks all,


-kevin



More information about the Losangeles-pm mailing list