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:
tcp_server_got_error => sub {
my ($heap, $operation, $errnum) = @_[HEAP, ARG0, ARG1];
$heap->{shutdown} = 1;
# Read error 0 is disconnect.
if ($operation eq 'read' and $errnum == 0) {
$client_disconnected->(@_);
}
else {
$client_error->(@_);
}
delete $heap->{client};
},
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.
tcp_server_got_error => sub {
my ($heap, $operation, $errnum, $errstr, $file_handle) =
@_[HEAP, ARG0, ARG1, ARG2, ARG3];
$heap->{shutdown} = 1;
$client_error->(@_);
delete $heap->{client}
unless ($operation eq 'read' and $errnum == 0);
},
sub _default_client_error {
warn( 'Client ', $_[SESSION]->ID,
" got $_[ARG0] error $_[ARG1] ($_[ARG2])\n"
);
# delete $_[HEAP]->{client};
}
So the question is how does one interpret a read error 0 on a socket?
>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.
Another idiosyncrasy I noticed is that the "Acceptor" parameter seems to
be a noop, and replaced by ClientConnected? Is this correct, Rocco?
Pete