[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