announcement: AnyEvent::Fork{,::RPC,::Pool}

Lee Aylward laylward at gmail.com
Thu Apr 25 00:25:53 CEST 2013


(resending this to the list)

Hi Marc,

I switched a few projects from AnyEvent::Worker to AnyEvent::Fork::Pool, and things seem to be working well so far!

One difference I noticed is error handling. WIth AE::Worker, your callback still gets called if there was an error, but with $@ set. I didn't see any mention of similar functionality for AE::Fork::RPC. Perhaps it exists and I missed it.

http://search.cpan.org/dist/AnyEvent-Worker/lib/AnyEvent/Worker.pm#SYNOPSIS

Additionally, a feature I think would be useful for AE::Fork::Pool is something like "max_requests". It would kill a worker after it handled a certain number of requests. Useful when using leaky libraries like ImageMagick.

-- 
Lee

On Apr 21, 2013, at 3:19 PM, Marc Lehmann <schmorp at schmorp.de> wrote:

> I mentioned it here and there, but now that the code is on CPAN, I'd like
> to announce it here.
> 
> There are a lot of modules on CPAN that create pools of worker processes,
> but all that I have seen have a fatal flaw: they use fork at runtime (and
> from perl) and do processing in the child. fork doesn't work safely in
> programs using pthreads, which is almost every program I write these days,
> and forking from a running program suffers form other hazards, such as
> having ltos of event watchers for things that only make sense in one of
> the process copies.
> 
> So here's my take on the problem:
> 
> AnyEvent::Fork (http://software.schmorp.de/pkg/AnyEvent-Fork)
> 
>   This module execs a new perl interpreter in a safe way, avoiding
>   both the fork-in-perl problem and fork-copies-everything problems.
> 
>   It is also surprisingly fast - despite the overhead, creating a process
>   via AnyEvent::Fork is often cheaper than using fork+exec, as fork has
>   to make a (virtual) copy of your whole process, and with AnyEvent::Fork
>   you can usualy make your copies from smaller processes that only
>   contain the code that you really need.
> 
>   Small example:
> 
>    AnyEvent::Fork
>       ->new
>       ->require ("MyModule")
>       ->run ("MyModule::server", my $cv = AE::cv);
> 
>    my $fh = $cv->recv;
> 
> The module doesn't, however, allow you to talk with the new processes, it
> only allows you to create them and run your code. To talk with them, there
> is:
> 
> AnyEvent::Fork::RPC (http://software.schmorp.de/pkg/AnyEvent-Fork-RPC)
> 
>   This module takes a process created with AnyEvent::Fork, and adds
>   simple RPC functionality, by running a simple server and giving you
>   a code reference that you can use to call a function in the other
>   process. It has a synchronous and an asynchronous backend (the async
>   backend uses AnyEvent and can handle multiple RPC calls in parallel).
>   Supports any serialiser you want.
> 
>   Small example:
> 
>    my $rpc = AnyEvent::Fork
>       ->new
>       ->require ("MyModule")
>       ->AnyEvent::Fork::RPC::run (
>          "MyModule::server",
>       );
> 
>   $rpc->(1, 2, 3, sub {
>       print "MyModule::server returned @_\n";
>   });
> 
> It doesn't, however, create some pool of processes for you or anything like
> that, which is why there is also:
> 
> AnyEvent::Fork::Pool (http://software.schmorp.de/pkg/AnyEvent-Fork-Pool)
> 
>   This uses a process created via AnyEvent::Fork as a template process
>   to create multiple worker processes. The pool of processes resizes
>   dynamically according to load and allows of variety of configurations.
> 
>   Small example:
> 
>    my $pool = AnyEvent::Fork
>       ->new
>       ->require ("MyWorker")
>       ->AnyEvent::Fork::Pool::run (
>            "MyWorker::run",
>            max => 4,
>         );
> 
>    for (1..10) {
>       $pool->(doit => $_, sub {
>          print "MyWorker::run returned @_\n";
>       });
>    }
> 
> Right now, AnyEvent::Fork seems to look pretty stable, and could use some
> real-world testing. AnyEvent::Fork::RPC is more like early beta, and
> AnyEvent::Fork::Pool is more like alpha quality at this point. The API
> might change if I find a bug that requires changing it, which is not at
> all unlikely at the moment.
> 
> The modules are also quite small (sloccount says all three together are
> 604 loc), and since they are completely seperate distributions on CPAN,
> you only pay for what you actually use.
> 
> Even windows us supported, to the extent possible (cygwin doesn't support
> any kind of handle-open or fd passing, and strawberry/activeperl of course
> are not getting better with time, and require the usual silly workarounds
> from your side).
> 
> My idea is not that everybody should go and start using AnyEvent::Fork::Pool -
> you are invited to do your own pools using AnyEvent::Fork::RPC. Or even
> ignore AnyEvent::Fork::RPC, and just use AnyEvent::Fork to create processes
> and do whatever you want with them.
> 
> It would however, be nice if more modules would use AnyEvent::Fork instead
> of some home-grown fork-and-hack-around-or-ignore-problems approach. Mostly
> new modules, as the design of AnyEvent::Fork makes it unsuitable as drop-in
> replacement for existing process pool managers.
> 
> However, modules such as AnyEvent::DBI could easily switch to
> AnyEvent::Fork, or AnyEvent::Fork::RPC, as they don't expose the
> implementation. And the CVS version of Gtk2::CV already uses
> AnyEvent::Fork, got a lot faster, and wastes a lot less memory.
> 
> In any case, as always, I release my code in the hope that is is useful to
> somebody, and can be safely ignored by the rest :)
> 
> -- 
>                The choice of a       Deliantra, the free code+content MORPG
>      -----==-     _GNU_              http://www.deliantra.net
>      ----==-- _       generation
>      ---==---(_)__  __ ____  __      Marc Lehmann
>      --==---/ / _ \/ // /\ \/ /      schmorp at schmorp.de
>      -=====/_/_//_/\_,_/ /_/\_\
> 
> _______________________________________________
> anyevent mailing list
> anyevent at lists.schmorp.de
> http://lists.schmorp.de/mailman/listinfo/anyevent
> 




More information about the anyevent mailing list