Acme::Fork::Lazy - abstract forking with lazy variables
use Acme::Fork::Lazy qw/:all/; use feature 'say'; ### # Single parallel calculation my $foo = forked { expensive_calculation_to_do_in_parallel() }; # ...then (sooner or later...) say $foo; ### # Parallel map my @list = map forked { sleep $_; $_*2 }, 1..10; sleep 5; # gives enough time for first 5 elements to be calculated say $_ for @list; ### END { wait_kids; # make sure we're not leaving behind any zombies }
We often want to fork a process with an expensive calculation. This involves making the child write the answer back to the parent, who will then have to poll the child occasionally to check if it answered back. There are abstractions, like Poe::Wheel::Run (lovely if you're already using POE). This is another one, using lazy variables:
forked
my $foo = forked { do_calculation() }; print "The answer was $foo\n";
forked returns a lazy calculation that will wait on the child process and return its result as a Perl data structure. If the child process isn't ready, then it will wait for it. This means that you could just as easily do:
my $foo = forked { do_calculation() }; do_some_stuff_that_might_take_about_the_same_time_as_calculation(); print "The answer was $foo\n";
without having to worry about polling etc. if the work in the main process didn't quite take long enough.
Note that the forked result must be a scalar.
wait_kids
END { wait_kids(); }
Place this anywhere that you'd like to stop and wait for the children to catch up, and in particular in an END block to avoid producing zombies.
Lots. Once those are resolved, we could upgrade this from Acme:: to Proc::Forked::Lazy.
Acme::
Proc::Forked::Lazy
The Lazy modules (see "SEE ALSO") are all currently broken in various exciting ways. So you may find that certain uses (like using Data::Dumper to output the result) won't trigger forcing the lazy result, and so on.
Only scalar values may be returned by a forked block.
No attempt is made to handle failure: timeouts/retry/error etc.
The client has to manually call wait_kids in END to make sure all kids exited cleanly.
Suggestions and patches for any of the above are very welcome (as well as new bug reports!)
The lazy semantics are provided by one of the following:
The original, by Audrey Tang
An ambitious and complex implementation by Nothingmuch.
A much simpler implementation.
The result is currently sent back from the child process coded in YAML.
If you can stomach POE, look at POE::Wheel::Run
Various IPC modules wrap fork in more or less palatable ways: IPC::Run, Proc::Fork, etc.
fork
(C) 2008 osfameron@cpan.org
This module is distributed under the same conditions as Perl itself.
To install Acme::Fork::Lazy, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Acme::Fork::Lazy
CPAN shell
perl -MCPAN -e shell install Acme::Fork::Lazy
For more information on module installation, please visit the detailed CPAN module installation guide.