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