Object::Wrapper::Fork::DBI -- Practice safe procs for forked DBI handles.
package My; use parent qw( Object::Wrapper::Fork::DBI ); # this supplies the constructor and cleanup # for Object::Wrapper used with database or # statement handles ("$dbh" or "$sth"). # # construcion looks just like DBI except for # the funny name: my $dbh = My->connect( $dsn, @blah ); # from here on in method calls just look like an # ordinary DBI unless they cross fork boundries. # in that case the forked proc will croak with # a mismatched-pid error. if( my $pid = fork ) { # feel free: this is in the same process. # this prepare (and prepare_cached) return # a wrapped statement handle. my $sth = $dbh->prepare( $sql ); } elsif( defined $pid ) { # any method calls to $dbh in here will # croak. undef-ing $dbh or just letting # it fall out of scope normally is fine. # # $dbh->prepare( $sql ) <-- this will die! undef $dbh; # this is safe ... exit 0 # or just let it go out of scope } else { die "Phorkafobia: $!" }
This just supplies minimal methods for the standard DBI constructors: connect, connect_cached, prepare, prepare_cached. These return wrapped objects which inherit from Object::Wrapper::Fork.
The "connect" method is a constructor that passes DBI-connect( @_ )> to Object::Wrapper::Fork::new.
DBI-
This is also where connect and connect_cached come from (anything else goes through the AUTOLOAD in O::F::Fork for sanity checks and gets passed along).
The supplied cleanup (most of this code) compares the current process id ("$$") with the pid that created the database handle. If the pid's match then DESTROY will finish any of { Driver }{ CachedKids } that are active and disconnect the database handle; if not then they all get { InactiveDestroy } set to true, the CachedKids structure is emptied and the $dbh undef-ed.
{ Driver }{ CachedKids }
{ InactiveDestroy }
The supplied cleanups check the pid and either finish the object if it is active or set InactiveDestroy.
Due to perly inheritence, and performance issues, the tied DBI interface is not supported: only method calls are dispatched properly.
Fortunately, DBI is well thought out enought that you probably never really need to use the tied interface in your code.
Top-level constructor and DESTROY that dispatches the cleanup for the wrapper contents.
Constructor supplies pid to Object::Wrapper::new, AUTOLOAD checks the original pid againsed $$.
Steven Lembark <lembark@wrkhors.com>
Copyright (C) 2009 Steven Lembark. This module is released under the same terms as Perl-5.10.0 itself.
To install Object::Wrapper, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Object::Wrapper
CPAN shell
perl -MCPAN -e shell install Object::Wrapper
For more information on module installation, please visit the detailed CPAN module installation guide.