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