[LA.pm] Apache::DBI pings

Benjamin J. Tilly ben_tilly at operamail.com
Mon May 16 17:57:55 PDT 2005


For the record.  I have similar misgivings, and prefer using regular
DBI's connect_cached to populate a global variable with the database
handle.

That strategy leads to a ping per page request, so that if anything
happens to the database connection, at most one page is affected
rather than every page until it decides to ping.

This does, of course, lead to an increased load due to pings.  I
personally consider this minor, since a ping or two is less than
everything ELSE I'm going to do in a page request.

Ben

"Kevin Scaldeferri" <kevin+lapm at scaldeferri.com> wrote:
> 
> 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
> 
> _______________________________________________
> Losangeles-pm mailing list
> Losangeles-pm at pm.org
> http://mail.pm.org/mailman/listinfo/losangeles-pm



More information about the Losangeles-pm mailing list