Skip Menu |

This queue is for tickets about the Apache-DBI CPAN distribution.

Report information
The Basics
Id: 29209
Status: resolved
Priority: 0/
Queue: Apache-DBI

People
Owner: pgollucci [...] p6m7g8.com
Requestors: nick [...] aevum.de
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: PerlCleanupHandler doesn't get called with MP2
Note: I built MP2 with MP_COMPAT_1X=0. Maybe that's the only reason for my problem. Apache::DBI is supposed to register a PerlCleanupHandler to rollback a database handle at the end of each request. This doesn't work with my MP2 setup. The code to register the handler is: if (!$Rollback{$Idx} and Apache->can('push_handlers')) { debug(2, "$prefix push PerlCleanupHandler"); if (MP2) { my $s = Apache2::ServerUtil->server; $s->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) }); } else { Apache->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) }); } # make sure, that the rollback is called only once for every # request, even if the script calls connect more than once $Rollback{$Idx} = 1; } First of all, Apache->can('push_handlers') returns false under MP2, at least if you built it with MP_COMPAT_1X=0. If you remove that check the cleanup handler is registered successfully, but it's still not called. Maybe this is because the handler is registered with the server, not the request. I had a look at the MP2 source code, but I can't find where the cleanup handlers are called.
From: nick [...] aevum.de
OK, I had a deeper look into this: Registering the cleanup handler with the server is indeed the culprit. It seems that the handler is appended to the per-dir config, but the per-dir config has already been evaluated at an earlier time. The attached patch makes Apache::DBI use the RequestRec to register the cleanup handler. This seems to work as expected.
--- lib/Apache/DBI.pm 2007-03-23 09:56:42.000000000 +0100 +++ /usr/lib/perl5/site_perl/5.8.0/Apache/DBI.pm 2007-09-06 19:41:41.000000000 +0200 @@ -9,6 +9,7 @@ if (MP2) { require mod_perl2; require Apache2::Module; + require Apache2::RequestUtil; require Apache2::ServerUtil; } elsif (defined $modperl::VERSION && $modperl::VERSION > 1 && @@ -137,18 +138,21 @@ # 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 # to temporarily turn off AutoCommit. - if (!$Rollback{$Idx} and Apache->can('push_handlers')) { - debug(2, "$prefix push PerlCleanupHandler"); + if (!$Rollback{$Idx}) { + my $r; if (MP2) { - my $s = Apache2::ServerUtil->server; - $s->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) }); + $r = Apache2::RequestUtil->request; + } + elsif (Apache->can('push_handlers')) { + $r = 'Apache'; } - else { - Apache->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) }); + if ($r) { + debug(2, "$prefix push PerlCleanupHandler"); + $r->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) }); + # make sure, that the rollback is called only once for every + # request, even if the script calls connect more than once + $Rollback{$Idx} = 1; } - # make sure, that the rollback is called only once for every - # request, even if the script calls connect more than once - $Rollback{$Idx} = 1; } # do we need to ping the database ?
Part of 1.07 now on CPAN