Up Prev Next
From: "Lenga, Yair " <yair dot lenga at citi dot com>
Subject: Automatically managing inactiveDestroy property.
Date: Apr 10 2008 12:38PM
I've posted the following questions to dbi-dev.
The short version is that I was hoping to have a way to manage the
"inactiveDestory" property on DBI drivers which can not work across fork
(e.g., DBD::Sybase). I've got a suggestion from Tim Bunce, which will
solve most of the cases - but require modifying third-party source code.
I'm hoping for a solution that does not require any source code changes
to third-party code.
My question/request: Will it make sense to add an option to the
DBD::Sybase as follows ?
= DBD::Sybase will remember the current PID when the object get created.
= If the DBD::Sybase object goes out of scope, it will not "DISCONNECT",
unless the current PID is the same as the saved PID.
= It should be possible to activate this features "externally"
(parameter on the connection string, env var, etc), even when the DBI
handle is not accessible.
As a side comment, I think it make sense to make this the default
behavior. I've been working with DBD::Sybase since version 0.13
(~1999?), and I can not recall a case where I wanted the Sybase
connection on the child process. I had many instances were I exteneded
existing programs using DBD::Sybase, which broke the DB connection,
because I forgot to explicitly manage the "inactiveDestory" property.
The rational for this change is that (in most situations), we do not
want to destroy the DBD::Sybase object in the child (after the fork).
Having to manually capture the fork, and manage the inactiveDestory is
very hard when using third party modules. As per feedback from dbi-dev,
the feature does not fit into DBI, because there are some drivers which
can work across fork calls (e.g., DBD::SQLite, and similar).
Thanks for taking the time to review this posting. Any feedback is
Original Posting to dbi-dev, and Tim's response listed below.
On Mon, Mar 24, 2008 at 12:04:48PM -0400, Lenga, Yair wrote:
> I have a complex CGI program, which need to call external program,
> while keeping the DBI connection open. I'm struggling with the
> "InactiveDestroy" property. Per the DBI perldoc:
> This attribute is specifically designed for use in Unix
> tions that "fork" child processes. Either the parent or the
> process, but not both, should set "InactiveDestroy" on all
> shared handles. Note that some databases, including
> Oracle, don't
> support passing a database connection across a fork.
> My problem is that I do not have any control over the interface to the
> external program (3rd party perl code that I can not modify), which is
> using both 'fork' and 'system'. In the past, I solved the problem
> using the following method:
> - Before calling the 3rd party library, the code will fork.
> - The child will mark the inactiveDestroy.
> - Code will call the 3rd party library
> - Parent wait for child to complete.
> This logic worked OK until I got extra requirements to store the
> results of the 3rd party calls in the DB. Initially, I tried to push
> the results from the child to the parent (using a pipe), but this is
> getting more complex - as I requirement expanded to pass more data
> between the 3rd party calls and the DB.
> My questions/suggestion:
> Will it make sense to manage the 'inactiveDestroy' automatically using
> one of the following policies:
> (A) Remember in the DBI handle the PID of the calling process, and
> assume the 'InactiveDestroy' was turned on when the handle goes out of
> scope on a process with a different PID (e.g, children). For me, this
> solution will provide a clean handling of all the cases.
> (B) Add a new property 'AutoInactiveDestroy' which will do the same.
> The code will have to turn this property on (when the connection is
> created, or before the fork).
> I can not think of any situation where (A) will not work - but my
> experience is limited to Linux/SunOS with Sybase/SQLITE/SQLServer.
> Any feedback will be appreciated.
> Yair Lenga
Tim Bunce suggested:
> Sounds like you could just set InactiveDestroy on all handles by
default, but then turn it off in the parent process just before it
> You could also possibly play games overriding CORE::GLOBAL::fork() and