logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

Object::ForkAware - Make an object aware of process forks and threads, recreating itself as needed

Acknowledgements

       The concept for this module came about through a conversation with Matt S.  Trout ("mst@shadowcat.co.uk")
       after experiencing the issue described in the synopsis on a prefork job-processing daemon.

       Some of the pid detection logic was inspired by the wonderful DBIx::Connector.

Author

       Karen Etheridge <ether@cpan.org>

Contributor

       Graham Knop <haarg@haarg.org>

Description

       If you've ever had an object representing a network connection to some server, or something else
       containing a socket, a filehandle, etc, and used it in a program that forks, and then forgot to close and
       reopen your socket/handle etc in the new process, you'll know what chaos can ensue. Depending on the type
       of connection, you can have multiple processes trying to write to the same resource at once, or
       simultaneous reads getting each other's data, dogs and cats living together... It's horrible, and it's an
       easy problem to run into.

       This module invisibly wraps your object and makes it fork-aware, automatically checking $$ on every
       access and recreating the object if the process id changes.  (The object is also thread-aware; if the
       thread id changes, the object is recreated in the same manner.)

       The object can be safely used with type checks and various type constraint mechanisms, as "isa" and "can"
       respond as if they were being called against the contained object itself.

       You can also ensure that a fork never happens, by making use of the optional "on_fork" handler:

           my $client = Object::ForkAware->new(
               create => sub { MyClient->new(server => 'foo.com', port => '1234') },
               on_fork => sub { die 'fork detected!' },
           );

       Or, if regenerating the object needs to be done differently than the initial creation:

           my $client = Object::ForkAware->new(
               create => sub { MyClient->new(server => 'foo.com', port => '1234') },
               on_fork => sub { MyClient->new(server => 'other.foo.com' },
           );

Limitations

       Using  the  Object::ForkAware  object with an operator that the containing object has overloaded will not
       work; behaviour is as if there was no operator overloading.  Partial support is possible, but is not  yet
       implemented.

Methods

"new(option=>val,option=>val...)"
       Provides an instance of this class.  Available options are:

       •   "create"  (mandatory)  -  a  sub reference containing the code to be run when the object is initially
           created (as well as recreated, if there is no "on_fork" sub provided), returning the object instance.
           If the object previously existed, it is passed as an argument to this method, allowing  you  to  copy
           any state from the old object to the new one.

       •   "on_fork"  -  a sub reference containing the code to be run when a fork is detected. It should either
           generate an exception or return the new object instance.  If the object  previously  existed,  it  is
           passed  as  an argument to this method, allowing you to copy any state from the old object to the new
           one.

       •   "lazy" - a boolean (defaults to false) - when true, the "create" sub is not called  immediately,  but
           instead deferred until the first time the object is used. This prevents useless object creation if it
           is not likely to be used until after the first fork.

       There  are  no  other  public  methods.  All  method  calls  on  the object will be passed through to the
       containing object, after checking $$ (or "threads->tid") and  possibly  recreating  the  object  via  the
       provided "create" (or "on_fork") sub.

Name

       Object::ForkAware - Make an object aware of process forks and threads, recreating itself as needed

See Also

       •   Object::Wrapper

       •   Object::Wrapper::Fork

       •   POSIX::AtFork

Support

       Bugs         may        be        submitted        through        the        RT        bug        tracker
       <https://rt.cpan.org/Public/Dist/Display.html?Name=Object-ForkAware> (or bug-Object-ForkAware@rt.cpan.org
       <mailto:bug-Object-ForkAware@rt.cpan.org>).

       I am also usually active on irc, as 'ether' at "irc.perl.org".

Synopsis

           use Object::ForkAware;
           my $client = Object::ForkAware->new(
               create => sub { MyClient->new(server => 'foo.com', port => '1234') },
           );

           # do things with object as normal...
           $client->send(...);

           # later, we fork for some reason
           if (fork == 0) {
               # child process
               $client->send(...);
           }

           # no boom happens! fork is detected and client object is regenerated

Version

       version 0.005

See Also