AnyEvent::Fork::RPC::event not propagating to parent

Art Sackett asackett at gmx.com
Tue Jan 10 05:26:16 CET 2017


Greetings, All:

I'm trying to read a 'tail -F /path/to/file' output via piped open in an
AnyEvent::Fork::RPC::Async child, and send the data back to the parent
by way of an on_event handler. With no luck; I issue the event by way of
AnyEvent::Fork::RPC::event but it never reaches the on_event handler of
the parent.

To illustrate with minimal code:

-----------------------------------------------------------------------
#!/usr/bin/perl 

use strict;
use warnings;

use AnyEvent;
use AnyEvent::Fork;
use AnyEvent::Fork::RPC;
use AnyEvent::Strict;

my $file = '/tmp/debug_test_case.txt';

if (shift) {
    undef $file;
}

my $tick = defined $file ? 
	AE::timer 3, 3,
	sub { my $now = scalar localtime; `echo $now >> $file` }
	:
	undef;

my $stop = AE::cv;
my ( $io, $tail_fh, $timer );

my $rpc = AnyEvent::Fork->new->require('AnyEvent::Fork::RPC::Async')->eval(
    do { local $/; <DATA> }
  )->AnyEvent::Fork::RPC::run(
    'run',
    async    => 1,
    on_error => sub { warn qq/ERROR: $_[0]\n/; exit 1; },
    on_event   => sub { warn qq/EVENT: $_[0]\n\n/ },
    on_destroy => $stop,
  );

$rpc->(
    $file,
    sub {
        warn qq/done callback: $_[0]\n/;
    }
);

$stop->recv();
undef $rpc;

__DATA__
sub run {
    my ( $callback, $file ) = @_;

    my $send_event = sub {
        my $msg = shift;
        my $warn = $msg =~ /\n/ ? $msg : $msg . "\n";
        warn qq/trying to send event: $warn/;
        return AnyEvent::Fork::RPC::event( $msg );
    };

    if ( defined $file && length $file) {
        if ( !open ( $tail_fh, '-|', 'tail', '-F', $file ) ) {
            warn qq/failed to open pipe to tail $file: $!\n/;
            exit 1;
        }

        $io ||= AnyEvent->io(
            fh   => $tail_fh,
            poll => 'r',
            cb   => sub {
                while (<$tail_fh>) {
                    if ( !defined AnyEvent::Fork::RPC::event ) {
                        warn qq/NO EVENT HANDLER PRESENT\n/;
                        return;
                    }
                    $send_event->($_);
                }
            },
        );
    } else {
        $timer ||= AE::timer 0, 3, sub {
            $send_event->('timer event ' . scalar localtime);
        };
    }
}
-----------------------------------------------------------------------

Running that, I get 'trying to send as event...' warnings every three
seconds when new lines appear in the file but the on_event callback is
never invoked. Adding an argument to the command line so the child only
runs a timer, without tailing or using AnyEvent->io, I get 'timer event'
as an event as expected.

Commenting out the on_event handler causes the expected "event received,
but no on_event handler" warning to be emitted.

In various other bits of code I've wrangled while working on this
problem I've implemented a custom serialiser that emits via warn() its
inputs and outputs. What I've seen happening is that '$rpc->($file...)'
results in an encode followed by a decode (arguments going to the
child), but then the child's calls to AnyEvent::Fork::RPC::event cause
only encodes -- the decode on the parent side never happens. Using the
other serialisers with built-in support (JSON, CBOR::XS, et al.) changes
nothing.

Can anyone see WTFFF(!) is wrong?

-- 
Art Sackett
http://www.artsackett.com/



More information about the anyevent mailing list