On Mon, Jul 20, 2009 at 8:15 AM, Nick Wellnhofer<wellnho...@aevum.de> wrote:
>
> Currently, Apache::DBI never disconnects from the database. This leads
> to the following warnings in my Postgres logs every time an Apache child
> exits:
>
> LOG:  unexpected EOF on client connection
>
> Depending on MaxRequestsPerChild this can really spam your Postgres logs.
>
> Attached is a patch against Apache::DBI that adds a PerlChildExitHandler
> in order to disconnect all existing database connections.
>
> Comments are welcome.

Added a check for the eval and warn, and patch to Changes.  I was
trying to think of a good way to test this, but Apache::DBI isn't
setup with Apache::Test yet.

+1 here, all current tests passing.

ph...@pooky ~/dev/svn/modperl/Apache-DBI/trunk $ svn diff
Index: lib/Apache/DBI.pm
===================================================================
--- lib/Apache/DBI.pm   (revision 796606)
+++ lib/Apache/DBI.pm   (working copy)
@@ -39,6 +39,8 @@
                                 #   a negative value de-activates ping,
                                 #   default = 0
 my %LastPingTime;               # keeps track of last ping per data_source
+my $ChildExitHandlerInstalled;  # set to true on installation of
+                                # PerlChildExitHandler

 # Check to see if we need to reset TaintIn and TaintOut
 my $TaintInOut = ($DBI::VERSION >= 1.31) ? 1 : 0;
@@ -134,6 +136,24 @@
         }
     }

+    # this PerlChildExitHandler is supposed to disconnect all open
+    # connections to the database
+    if (!$ChildExitHandlerInstalled) {
+        $ChildExitHandlerInstalled = 1;
+        my $s;
+        if (MP2) {
+            $s = Apache2::ServerUtil->server;
+        }
+        elsif (Apache->can('push_handlers')) {
+            $s = 'Apache';
+        }
+        if ($s) {
+            debug(2, "$prefix push PerlChildExitHandler");
+            $s->push_handlers(PerlChildExitHandler => \&childexit);
+        }
+    }
+
+
     # this PerlCleanupHandler is supposed to initiate a rollback after the
     # script has finished if AutoCommit is off.  however, cleanup can only
     # be determined at end of handle life as begin_work may have been called
@@ -216,6 +236,24 @@
     1;
 }

+# The PerlChildExitHandler disconnects all open connections when the
+# httpd child exits
+sub childexit {
+
+    my $prefix = "$$ Apache::DBI            ";
+    debug(2, "$prefix PerlChildExitHandler");
+
+    foreach my $dbh (values(%Connected)) {
+
+        eval { DBI::db::disconnect($dbh) };
+        if ($@) {
+            warn("error disconnecting db handle: $@");
+        }
+    }
+
+    1;
+}
+
 # The PerlCleanupHandler is supposed to initiate a rollback after the script
 # has finished if AutoCommit is off.
 # Note: the PerlCleanupHandler runs after the response has been sent to
Index: Changes
===================================================================
--- Changes     (revision 796606)
+++ Changes     (working copy)
@@ -2,6 +2,9 @@

 1.08

+  - Adds PerlChildExitHandler to disconnect existing connections
+    Submitted by: Nick Wellnhoffer <wellnho...@aevum.de>
+
 1.07 05/09/2008
   - http://rt.cpan.org/Public/Bug/Display.html?id=31003
     Submitted by: diaf...@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org
For additional commands, e-mail: dev-h...@perl.apache.org

Reply via email to