Detecting EOF in a on_read for AnyEvent::Handle
Marc Lehmann
schmorp at schmorp.de
Mon Dec 12 13:58:29 CET 2011
On Sun, Dec 11, 2011 at 03:26:57PM -0500, Marios Titas <redneb8888 at gmail.com> wrote:
> client connects and send a request which consists of one line of text.
> Then the server responds by sending back one line of text. Then the
> client can send another request and so on. When the client has
> received a response from the server it might close the connection
> instead of sending a new request. This should not be treated as an
> error.
> The AnyEvent::Handle man page provides two examples of serving
> requests in a loop. The first one doesn't work for the above case
> because it cannot handle the EOF correctly (it will throw an error).
It certainly _does_ handle EOF correctly: an unexpected EOF is an error
condition in that protocol - this is explained in the text as well.
> The second doesn't have this problem, but it has a different problem:
> as soon as some data is received, is will handle the request
> immediately. But this is not desired in many cases.
You can delay request processing in any way you like, AnyEvent::Handle
doesn't force you to handle requests immediately.
What AnyEvent::Handle forces you is to implement your request processing
in an event-based way. If you don't want to do that for whatever reason,
then AnyEvent::Handle is the wrong interface indeed, and you should use
blocking calls, which make it much easier to not react tot he socket when
you are busy (it's automatic in fact).
> required that the server finishes processing the previous request
> before it moves on to the new one. This is for example how HTTP works.
If you mean pipelining, then, well AnyEvent::Handle doesn't force you to
write your reply in the callback: you can write it at any later time as well.
If you don't want to read from the socket temporarily you can ->stop_read.
However, the latter is not very efficient, and HTTP doesn't require you
to do that. HTTP certainly *does* expect you to read if you can, for
efficiency reasons when pipelining, so it seems you want to implement an
inefficient HTTP server or something like that. It's possible, but not the
default with AnyEvent::Handle.
> So here's an implementation of such a server that doesn't have the
> above issues. The problem is that it relies on the
> undocumented$handle->{_eof}:http://pastebin.com/utMuKY8e
That server is obviously buggy - you should not need to hack round in
anyevent::handle's internals to do that.
The second example from the faq that you refer to should behave fine in
your case: "push_read (line..." in on_read will detect any errors due to
partial transmission of a request, while not causing an error when the
server receives an EOF on a request boundary.
If you can't handle client data when it receives you either have to
postpone it, tell the handle to stop reading, or use a blocking approach
where you don't read as long as you handle a request.
--
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