|Think about Loose Coupling|
Fork-safe DBI handles via ChildHandles and InactiveDestroyby etcshadow (Priest)
|on Jun 07, 2007 at 03:30 UTC||Need Help??|
etcshadow has asked for the
wisdom of the Perl Monks concerning the following question:
The setup: I'm working on some code that involves forking in a process with potentially several open DBI database handles (dbhs) to Oracle database handles. Oracle dbhs will encounter problems when the child processes terminate unless they have the InactiveDestroy attribute set on them in the child processes. Otherwise, essentially, when the child process terminates, during its global destruction phase, every dbh reports back to its respective database that the connection has terminated, which means that Oracle will not accept any further activity on that connection (from other processes). Even if that connection was never used in the child process, the mere act of the child process coming into existence and then exiting will foul the parent process's database handle... unless of course this InactiveDestroy attribute is set. The whole purpose of the InactiveDestroy attribute is, basically, to make the DESTROY on the dbh "inactive", i.e. it doesn't send a message to Oracle to the effect of "I'm dead, ignore any future communications from me".
So, anyway, because I may be performing a fork deep down inside of a function call, I may not be able to easily pull a list of all the dbhs that are hanging around in the process, waiting to get passively disrupted by the fork. At least, I hadn't been able to do so in the past. However, DBI has somewhat recently (I don't know when exactly) introduced an attribute called ChildHandles which returns an array of weak-referrences to all the child handles of a given handle object. This allows me to something like this:
Which, if called as the first thing in the child process, will prevent the child's global destruction from fouling all of the dbhs in the parent. This seems like a complete answer to my problems.
The real question though, is if this is a safe action to take. The DBI docs on the ChildHandles attributes state explicitly that "The referenced array returned should be treated as read-only." I'm a little concerned (perhaps overly concerned) over the specific semantics of this. Does it mean that the array, itself should not be altered (like adding or removing elements to the array), or does it mean that the array contents should not be altered? Is anybody here familiar enough with the DBI internals to know? Am I just being paranoid for even asking? :-)
I have tested this, and it seems to work fine, but I don't know if there are any gremlins hiding in their that will bite me over this. It seemed like a good idea to at least ask.
Thanks in advance.