On Fri, Jul 12, 2002 at 12:10:23PM -0400, Peter Chen wrote:
> On Thu, 2002-07-11 at 20:18, Peter Chen wrote:
> > With Fletch's blessing, I have adapted POE-Component-SOAP to use
> > POE-Component-Server-TCP.  However, I am seeing some strange socket
> > behavior that causes the SOAP server to fail sporadically, which I
> > believe is related to output buffer flushing.
> 
> After more debugging, I found out what the problem was.  The key is the
> interpretation of a read error 0 on a socket.  Here is the original code
> in PoCo-Server-TCP 1.22, dated 6/18/2002:

[code that deletes the wheel on error 0]

> Note that a read error 0 on the socket is interpreted as a disconnect,
> and POE::Wheel::ReadWrite stored in $heap->{client} is deleted
> afterward.  Consequently if the output buffer is not empty at the time,
> the buffer content may never get flushed.
> 
> Changing the code for tcp_server_got_error callback, and
> _default_client_error to the following seems to fix this.

[code that does a shutdown on error 0]

> So the question is how does one interpret a read error 0 on a socket?

Read error 0 signals an EOF on a socket.  It means the socket will not
provide more data to be read.  I have been interpreting that as a
disconnect, but it's clear I've been wrong to do it.

Read error 0 can be triggered without a disconnect when the remote end
calls shutdown(SOCK,1) (see perldoc -f shutdown).  That signals no
more data to be read, but it does not (and should not) imply that the
caller is done receiving.

> From the behavior I observe, where a read error 0 could occur while the
> client is still waiting for a response from the server, it seems to
> indicate it's possible for the server to get a read error 0, which is
> usually interpreted as the file handle being closed, and still be able
> to write.  So it seems to be premature to delete the wheel upon such an
> error.

You are correct.  I will apply your fix to the TCP client and server
components.  I also need to stop recommending that wheels be deleted
on read error 0.

Attached is a program I wrote to test shutdown() behavior on sockets.

> Another idiosyncrasy I noticed is that the "Acceptor" parameter seems to
> be a noop, and replaced by ClientConnected?  Is this correct, Rocco?

When Acceptor is supplied, all the /Client.*/ callbacks are disabled.
It becomes the programmer's responsibility to define every detail of
how a client connection is handled.  This was the old Server::TCP
behavior, and Acceptor was left in the component to ensure backward
compatibility.

You've noticed that it's broken, though.  I'm surprised nobody noticed
it; maybe it doesn't need to be backward compatible after all?

Anyway, it will be fixed in CVS this weekend.

-- Rocco Caputo / [EMAIL PROTECTED] / poe.perl.org / poe.sf.net

Reply via email to