tcp_server + AnyEvent::Handle
Сергей Алексеев
perllance at yandex.ru
Wed Apr 30 10:25:34 CEST 2014
30.04.2014, 02:10, "Marc Lehmann" <schmorp at schmorp.de>:
> On Wed, Apr 30, 2014 at 12:12:48AM +0400, Sergei <perllance at yandex.ru> wrote:
>
>> I have a tcp_server and I want to use AnyEvent::Handle to manage the read and write queue.
>> My code looks something like this (see below, very simple). The problem is that my read handler is missing some initial data from the $fh.
>
> Missing means?
Missing means that AnyEvent::Handle does not invoke my on_read handle even though some data has been written to the socket by the remote client. Below, I explain why it happens.
>
>> Obviously, by the time the $hdl object is instantiated, $fh already contains some data. I can circumvent this by trying to sysread from the $fh first, but the data is not necessarily there, so I'll have to write conditions and callbacks which makes my code clumsy and duplicates AnyEvent::Handle.
>
> What do you mean "contains some data"?
I mean that data has been written to this socket by the remote client which can be easily read using perl sysread command like this:
sysread($fh, my $buffer, $length);
which I can easily do and which will solve my problem. But I don't like this solution and I want AnyEvent::Handle do this for me. But it doesn't.
$fh doesn't contain any data at
> all, it's just a filehandle, and no data has been read into its buffers by
> tcp_server (nor will AnyEvent::Handle read any data into its buffer).
Apparently, data has been read into its buffers by the tcp_server.
>
>> Ideally, AnyEvent::Handle would have some parameter in its constructor which would drain the $fh so that I can rely on AnyEvent::Handle methods only and avoid sysread in my code. Or there is got to be a way to trigger a read event on the $fh which would make AnyEvent::Handle to process whatever was written to the $fh so far.
>
> I am not sure what you mean with "drain", it feels as if draining would be
> your problem, not the solution.
In the start_read method, AnyEvent::Handle creates an IO watcher on the filehandle which waits for new data to arrive. But it doesn't check whether there is any data already available for read from that filehandle. There should be a way to tell AnyEvent::Handle to try to ready from the filehandle. That's what I mean by "drain".
>
> In any case, AnyEvent::Handle doesn't have a notion of "initial data",
> the data that is still in the kernel sockets buffer will be delivered
> normally, while the data already read is not visible to AnyEvent::Handle
> at all anymore.
It is not some special "initial data". It is just the bytes of data which come first. And these bytes have been perfectly delivered to the buffer. But there is no way to tell AnyEvent::Handle to pick that data.
>
>> tcp_server '127.0.0.1', '123', sub {
>
> Your code will likely never call any callback, as it creates and destroys
> $hdl instantly.
It was just to illustrate how AnyEvent::Handle object is instantiated and its relative place in the accept callback.
>
> --
> The choice of a Deliantra, the free code+content MORPG
> -----==- _GNU_ http://www.deliantra.net
> ----==-- _ generation
> ---==---(_)__ __ ____ __ Marc Lehmann
> --==---/ / _ \/ // /\ \/ / schmorp at schmorp.de
> -=====/_/_//_/\_,_/ /_/\_\
More information about the anyevent
mailing list