how to use AnyEvent::Handle on the child of AnyEvent::Run (aka portable_socketpair)?

Andrew Whatson whatson at gmail.com
Wed Nov 20 04:49:52 CET 2013


OK, I can replicate what you're seeing by selecting the pure-perl
AnyEvent backend.  This is used as a fall-back when the EV module has
not been installed.  If possible, I'd recommend installing EV, adding
it to your list of things to install for AnyEvent, and not worrying
about the pure-perl backend any more ;)  Once EV is installed, it will
be used as the default backend - you can set PERL_ANYEVENT_MODEL=Perl
to force the pure-perl backend if necessary.

As for *why* the pure-perl backend exhibits this behaviour, that
requires further investigation.

On 20 November 2013 13:28, Fulko Hew <fulko.hew at gmail.com> wrote:
>
> On Tue, Nov 19, 2013 at 8:16 PM, Andrew Whatson <whatson at gmail.com> wrote:
>>
>> Anywhere before "first send to child" should work.  Without this, I
>> see the following output sometimes:
>>
>>   parent rx: child timer
>>   parent tx
>>   parent rx: child timer
>>   child rx: sent to child
>>
>> The "child timer\n" and "child rx: sent to child\n" messages are being
>> received together, due to output buffering in the child process.
>> Turning on autoflush forces the process to send each line separately.
>>
>> I hope this is the problem you're seeing - if not, please explain the
>> problem in more detail.
>
>
> I don't think its the same problem.
> With or without the autoflush, I see the same results:
>
> parent tx first send
> parent rx: child started
> parent rx: child timer
> parent tx
> parent rx: child timer
> parent rx: child timer
> parent tx
>
> I think its a problem on the receiving end because if I change
> the receiver to the code below (without the autoflush),
> just to test the 'echo' part (without the child timer async sender)
> the child _does_ receive and transmit.
>
> sub child_proc {
>     while (1) {
>         chomp (my $d = <STDIN>);
>         print STDERR "child rx: $d\n";;
>         send_msg_to_parent("echoing...$d");
>         sleep 1;
>     }
> }
>
>
> On 20 November 2013 10:40, Fulko Hew <fulko.hew at gmail.com> wrote:
>> On Tue, Nov 19, 2013 at 7:16 PM, Andrew Whatson <whatson at gmail.com> wrote:
>>>
>>> Hi Fulko,
>>>
>>> I think you need to turn on autoflush on STDOUT.  After putting $|=1,
>>
>> Where did you put it, because no mater what I do,
>> it doesn't make a difference for me.
>>>
>>> I get the following output which seems correct:
>>>
>>> parent tx 'first send'
>>> parent rx: child started
>>> parent rx: child rx: first send to child
>>>
>>> parent rx: child timer
>>> parent tx
>>> parent rx: child rx: sent to child
>>>
>>> parent rx: child timer
>>> parent tx
>>> parent rx: child timer
>>> parent rx: child rx: sent to child
>>>
>>> parent rx: child timer
>>> parent tx
>>> parent rx: child rx: sent to child
>>>
>>> Regards,
>>> Andrew Whatson
>>>
>>> On 20 November 2013 06:03, Fulko Hew <fulko.hew at gmail.com> wrote:
>>> > I'm trying to use AnyEvent:Run, but I need to make my child smarter.
>>> > and make it an AnyEvent style process that uses 'event driven I/O'.
>>> > But I can't seem to get anywhere, and I'm obviously missing...
>>> > something.
>>> >
>>> > I'm attempting the test example below.
>>> >
>>> > What I see is the child successfully sending and the parent receiving.
>>> > But I'm not getting the parent-to-child pat,  and I don't know if its a
>>> > problem in parent or in the child, or I'm just doing it wrong.
>>> >
>>> > use strict;
>>> > use warnings;
>>> > use Socket;
>>> > use AnyEvent;
>>> > use AnyEvent::Run;
>>> > use AnyEvent::Handle;
>>> >
>>> > sub send_msg_to_parent { print "$_[0]\n"; }
>>> >
>>> > sub child_proc {
>>> >     my $child_hdl = new AnyEvent::Handle (
>>> >         fh  => \*STDIN,
>>> >         on_read => sub {
>>> >                        my $hdl = shift;
>>> >                        my $d = $hdl->{rbuf};
>>> >                        $hdl->{rbuf} = '';
>>> >                        send_msg_to_parent("child rx: $d");
>>> >                        },
>>> >     );
>>> >     my $child_timer = AnyEvent->timer (  # send a watchdog msg
>>> >         after       => 2,
>>> >         interval    => 2,
>>> >         cb          => sub {send_msg_to_parent("child timer"),
>>> >     );
>>> >     send_msg_to_parent("child started");
>>> >     my $child_cv = AnyEvent->condvar;
>>> >     $child_cv->wait;
>>> > }
>>> >
>>> >
>>> > my $child = AnyEvent::Run->new(
>>> >     cmd     => sub { child_proc() },
>>> >     on_read => sub {
>>> >                    my $hdl = shift;
>>> >                    my $d = $hdl->{rbuf};
>>> >                    $hdl->{rbuf} = '';
>>> >                    print "parent rx: $d";
>>> >                    },
>>> >     on_error    => sub { print "child died\n"; },
>>> > );
>>> > my $parent_timer = AnyEvent->timer (
>>> >     after       => 3,
>>> >     interval    => 3,
>>> >     cb          => sub { $child->push_write("sent to child\n"); print
>>> > "parent tx\n";},
>>> > );
>>> > $child->push_write("first send to child\n"); print "parent tx 'first
>>> > send'\n";
>>> > my $cv = AnyEvent->condvar;
>>> > $cv->wait;
>>> >
>>> >
>>> > _______________________________________________
>>> > anyevent mailing list
>>> > anyevent at lists.schmorp.de
>>> > http://lists.schmorp.de/mailman/listinfo/anyevent
>>
>>
>



More information about the anyevent mailing list