.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Object::ForkAware 3pm" .TH Object::ForkAware 3pm "2022-12-04" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Object::ForkAware \- Make an object aware of process forks and threads, recreating itself as needed .SH "VERSION" .IX Header "VERSION" version 0.005 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& use Object::ForkAware; \& my $client = Object::ForkAware\->new( \& create => sub { MyClient\->new(server => \*(Aqfoo.com\*(Aq, port => \*(Aq1234\*(Aq) }, \& ); \& \& # 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 .Ve .SH "DESCRIPTION" .IX Header "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. .PP This module invisibly wraps your object and makes it fork-aware, automatically checking \f(CW$$\fR 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.) .PP The object can be safely used with type checks and various type constraint mechanisms, as \f(CW\*(C`isa\*(C'\fR and \f(CW\*(C`can\*(C'\fR respond as if they were being called against the contained object itself. .PP You can also ensure that a fork never happens, by making use of the optional \&\f(CW\*(C`on_fork\*(C'\fR handler: .PP .Vb 4 \& my $client = Object::ForkAware\->new( \& create => sub { MyClient\->new(server => \*(Aqfoo.com\*(Aq, port => \*(Aq1234\*(Aq) }, \& on_fork => sub { die \*(Aqfork detected!\*(Aq }, \& ); .Ve .PP Or, if regenerating the object needs to be done differently than the initial creation: .PP .Vb 4 \& my $client = Object::ForkAware\->new( \& create => sub { MyClient\->new(server => \*(Aqfoo.com\*(Aq, port => \*(Aq1234\*(Aq) }, \& on_fork => sub { MyClient\->new(server => \*(Aqother.foo.com\*(Aq }, \& ); .Ve .SH "METHODS" .IX Header "METHODS" .ie n .SS """new(option => val, option => val...)""" .el .SS "\f(CWnew(option => val, option => val...)\fP" .IX Subsection "new(option => val, option => val...)" Provides an instance of this class. Available options are: .IP "\(bu" 4 \&\f(CW\*(C`create\*(C'\fR (mandatory) \- a sub reference containing the code to be run when the object is initially created (as well as recreated, if there is no \&\f(CW\*(C`on_fork\*(C'\fR 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. .IP "\(bu" 4 \&\f(CW\*(C`on_fork\*(C'\fR \- 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. .IP "\(bu" 4 \&\f(CW\*(C`lazy\*(C'\fR \- a boolean (defaults to false) \- when true, the \f(CW\*(C`create\*(C'\fR 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. .PP There are no other public methods. All method calls on the object will be passed through to the containing object, after checking \f(CW$$\fR (or \f(CW\*(C`threads\->tid\*(C'\fR) and possibly recreating the object via the provided \f(CW\*(C`create\*(C'\fR (or \f(CW\*(C`on_fork\*(C'\fR) sub. .SH "LIMITATIONS" .IX Header "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. .SH "ACKNOWLEDGEMENTS" .IX Header "ACKNOWLEDGEMENTS" The concept for this module came about through a conversation with Matt S. Trout (\f(CW\*(C`mst@shadowcat.co.uk\*(C'\fR) after experiencing the issue described in the synopsis on a prefork job-processing daemon. .PP Some of the pid detection logic was inspired by the wonderful DBIx::Connector. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 Object::Wrapper .IP "\(bu" 4 Object::Wrapper::Fork .IP "\(bu" 4 POSIX::AtFork .SH "SUPPORT" .IX Header "SUPPORT" Bugs may be submitted through the \s-1RT\s0 bug tracker (or bug\-Object\-ForkAware@rt.cpan.org ). .PP I am also usually active on irc, as 'ether' at \f(CW\*(C`irc.perl.org\*(C'\fR. .SH "AUTHOR" .IX Header "AUTHOR" Karen Etheridge .SH "CONTRIBUTOR" .IX Header "CONTRIBUTOR" Graham Knop .SH "COPYRIGHT AND LICENCE" .IX Header "COPYRIGHT AND LICENCE" This software is copyright (c) 2013 by Karen Etheridge. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.