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