how to use AnyEvent::Handle on the child of AnyEvent::Run (aka portable_socketpair)?
Fulko Hew
fulko.hew at gmail.com
Wed Nov 20 16:10:06 CET 2013
On Wed, Nov 20, 2013 at 4:21 AM, Marc Lehmann <schmorp at schmorp.de> wrote:
> On Wed, Nov 20, 2013 at 05:56:42PM +1000, Andrew Whatson <
> whatson at gmail.com> wrote:
> > After further investigation, it seems the problem is caused by the
> > fact that constructing AnyEvent::Run with an "on_read" parameter
> > causes a read watcher for the socketpair to be created *before*
> > forking. This watcher then exists in both the parent and child,
> > causing some weird behaviour.
>
> Well spotted.
>
Thank you,
I
failled/
forgot to realize it was doing that; it was never
my intent
to attempt to inherit event handling in the child.
@fulko:
>
> Forking in a program using AnyEvent and then trying to use event handling
> in both parent and child is doomed from the beginning, because you never
> know who registered which watchers, and they are either active in both
> parent and child, or (with many of the more advanced event loops that are
> not EV) will not even work. (the FORK section in the AnyEvent manpage goes
> into a little bit more detail, as Andrew also pointed out).
>
> The only safe way to use fork from perl is to use something like
> Proc::FastSpawn (when threads are involved you need to fork+exec from C
> code) or the good old fork+exec (in all other cases). Or in other words,
> fork is to start new programs via exec, not for parallel processing.
>
> Trying to do parallel processing with fork is not going to work except in
> the most simplest cases in completely controlled conditions (event loop is
> known, all of the code is known).
>
Because Perl threading would force my variable-sharing issues to be
extremely
complicated, I wanted to move instead to: a simple, low-count, multi-process
approach with a simple (JSON) message passing between them.
... snip ...
> > The work-around is to set on_read afterwards:
> >
> > my $child = AnyEvent::Run->new(cmd => sub { ... });
> > $child->on_read(sub { ... });
>
> While this can work in this case, it relies on undocumented behaviour
> inside Anyevent::Run, and in general has a very fragile dependency on code
> that is generally outside of ones control (for example, AnyEvent, during
> intiialisation, might create any number of watchers that will malfunction.
> Even if AnyEvent doesn't do it, the event loop itself might. Even if the
> event loop might not do it, other modules might. And so on.).
>
.
.. snip ...
> > It seems to me that this behaviour could be considered a bug in
> > AnyEvent::Run. The patch to fix it there is straightforward, we just
> > move AnyEvent::Handle construction into the parent section after the
> > call to fork.
>
> No, it's a design bug in the original program - AnyEvent::Run cannot
> ensure that _all_ existing watchers play nicely after fork, and generally
> shouldn't need to.
>
> This is really the same problem as calling exit in a forked subprocess and
> wondering why things break, or not setting cloexec on file descriptors
> (that you might not even know of) and wondering why things break, or
> forking from a threaded program and wondering why things break, and so on.
>
> fork should be followed by exec or _exit. Trying to do event processing is
> simply doomed, and AnyEvent::Run can not ensure anything.
>
I appreciate the benefits of fork-exec but, to make my application safe,
isn't there just a simple way of 'undef'ing (in the child),
anything that AnyEvent or its event loops _might_ have created,
(if its done early enough)?
Since I haven't found a way to 'easily' share complex data structures
between my few, non-AnyEvent compatible 'threads' (that run forever),
I find my alternative is to create separate processes for each with
simple message passing between them. And for code management purposes,
I'd like to keep it all within a single file.
I don't really want to incur the complexity of getting my appropriate
information passed through to the exec'ed application; or to recreate
the portable_socketpair communications between my parent and children
(that seems so easy because it comes with AnyEvent::Run)
[primarily because I don't understand the details of doing it myself].
:-(
Fulko
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.schmorp.de/pipermail/anyevent/attachments/20131120/027f59ec/attachment.html>
More information about the anyevent
mailing list