On Sat, Nov 05, 2005 at 12:20:57PM -0800, Aaron Turner wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> So I'm trying to track down a problem with my program which forks  
> needing both parent and children to have access to the database via  
> Class::DBI.  The basic issue I'm having is that after the first child  
> exits, the parent's DBI connection seems to get mangled, because it  
> can no longer find the prepared statements created by Class::DBI.   

Enabling DBI trace in the client may shed some light on it. The DBD::Pg
driver may not be honouring InactiveDestroy.

Tim.

> I've written a custom db_Main() and connection() which keeps track of  
> the $dbh in a closure in my Class which is inheriting from  
> Class::DBI.  In the child, I run:
> 
> $dbh->{InactiveDestroy} = 1;
> $dbh = undef;
> MyClass::DBI->connect();
> 
> Inspecting the $dbh hashref in the parent/children, I see what I  
> expect: parent keeps the same handle before and after fork(),  
> children at first inherit the handle, but then get their own after  
> calling connect().
> 
> 
> But it seems that this issue is happening at the DBI layer and I'm lost.
> 
> - ----------------------------------------------------------------------
> 
> From my main Class::DBI class:
> 
> package Mu::DBI;
> use base 'Class::DBI';
> use IPC::Open3;
> use IPC::Open2;
> use IO::Select;
> use Tie::IxHash;
> use DBI;
> use Carp qw/croak cluck confess carp/;
> 
> 
> my $dbh; # our dbh handle
> 
> # figure out where and how to connect
> sub dsn {
>     return "dbi:Pg:dbname=" . Mu::Config->DATABASE .
>     ";host=" . Mu::Config->DBHOST .
>     ";port=" . Mu::Config->DBPORT .
>     Mu::Config->DBOPTIONS;
> }
> 
> # replacement for Class::DBI->db_Main()
> sub db_Main() {
>     return $dbh;
> }
> __PACKAGE__->_remember_handle('Main');
> 
> # We have to undef our current handle, before the child can
> # reconnect
> sub undef_dbh() {
>     $dbh = undef;
> }
> 
> # Use Mu::DBI->connect() instead of connection() so we use our
> # own $dbh rather then the one provided with Class::DBI
> sub connect() {
> 
>     # Class::DBI expects to inherit from DBIx::ContextualFetch
>     my $dbenv = Mu::Config->DBENV;
>     $dbenv->{RootClass} = "DBIx::ContextualFetch";
> 
>     $dbh = DBI->connect(Mu::DBI->dsn, Mu::Config->DBUSER,
>     Mu::Config->DBPASS, $dbenv) or
>         croak("Can't connect to DB: $DBI::errstr");
> 
>     $dbh->do('SET search_path = "mucore","muapp","muserver";');
>     return 1;
> }
> 
> 
> - ----------------------------------------------------------------------
> 
> From my forking code:
> 
> Mu::DBI->connect();
> my $dbh = Mu::DBI->db_Main();
> [ do some DB stuff here... ]
> 
> while (some test) {
>       [ Do some DB work here... ]
> 
>       if ($pid = fork()) {
>               # parent
>               # do some basic stuff here...
>               $SIG{CHLD} = \&REAPER;
> 
>       } else {
>               croak("Failed to fork: $!") unless defined $pid;
> 
>               # now we're in the child, so reconnect to the DB
>               # so that the parent doesn't loose it's handle
>               if (! ($dbh->{InactiveDestroy} = 1)) {
>                               croak("Why can't i turn off destroy? " . 
>                               DBI::errstr);
>               }
>               Mu::DBI->undef_dbh();
>                       Mu::DBI->connect();
> 
>               [ do some DB stuff here... ]
>       }
> 
> }     
> 
> - --
> Aaron Turner, Sr. Security Engineer                    
> <[EMAIL PROTECTED]>
> Ph: 408.329.6320          Fax: 408.329.6317
> 
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.2 (Darwin)
> 
> iD8DBQFDbRQvklVhPAXg8nARAsCpAJ9dKPS6Co72s1E3u6cDSF1JCPSBcwCgiFtn
> gpl5vHmImx2JQApsHpVKugY=
> =tOqd
> -----END PGP SIGNATURE-----

Reply via email to