RFC: AnyEvent::Handle with two non-duplex filehandles

Mark Lawrence nomad at null.net
Mon Apr 22 05:37:54 CEST 2013


> > called via ssh, similar to the way git uses ssh as a transport
> > mechanism. Communication with the server program therefore occurs
> > via two separate file handles, one for reading and one for writing.
> 
> Can you explain where the requirement to use two handles comes from?
> Normally, when communicating with ssh, one handle should suffice
> (reading for ssh output, and writing for ssh input, plus maybe
> another read handle for stderr). At least, it worked for me in the
> past.

I wish I only had one handle for reading and writing to ssh, but how do
you arrange that? The inter-process communication tools I've seen
(open(), IPC::* etc) all seem to return or require separate in/out
handles. Is there a trick I'm not aware of for combining the child
process Stdin and Stdout filehandles into one?

> > (sockets), but requires the use of two separate instances for the
> > ssh-transport case. In my case (presumably a common one?) the read
> 
> I have yet to see a case where this problem occurs. I think for those
> (presumably rare :) cases, using two ae handles for two perl handles
> is quite natural.
> 
> > callbacks need to call write handle methods, and vice-versa, and
> > keeping track of objects and reference loops is complex. 
> 
> I think using weak references or explicit ->destroy calls should take
> care of these loops without too much effort.

I think the challenge I am facing is not knowning all of the places I
should be using ->destroy. However weakening the references (which I
haven't used here yet) may well sort things out.

I'm facing something of a call-back hell due to needing to maintain
state between events, possibly resulting in lexical variables (i.e.
filehandles) being passed into multiple anonymous subrefs where I
assume they are not weak:

    $state = calculate_state();
    $whl->push_write(...);

    $rdl->push_read(line => sub {
        $state = calculate_state_again();

        # handle the read, and then push another write...
        $whl->push_write(...);
        $rdl->push_read(...);
    });

The above feels kind of messy though, and if a write error has occured
before the push_read callback occurs... well, I have to do a lot of
checking. A single handle for reading and writing would definately be a
better option. The general style I use above could probably also do
with some work, which I will possibly visit in another mail.

Mark.
-- 
Mark Lawrence



More information about the anyevent mailing list