-----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. 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