Commit ef2ab695 authored by Jeremy Hylton's avatar Jeremy Hylton

Merge in zeo-1_0-branch

Wrap send() and recv() calls in try/except

The try/except catches errors like EAGAIN that indicate transient
failures.  In those cases, treat as send() and recv() of no data and
return from method gracefully.
parent 52b8c629
......@@ -85,11 +85,30 @@
"""Sized message async connections
"""
__version__ = "$Revision: 1.10 $"[11:-2]
__version__ = "$Revision: 1.11 $"[11:-2]
import asyncore, string, struct, zLOG, sys, Acquisition
import socket, errno
from zLOG import LOG, TRACE, ERROR, INFO
# Use the dictionary to make sure we get the minimum number of errno
# entries. We expect that EWOULDBLOCK == EAGAIN on most systems --
# or that only one is actually used.
tmp_dict = {errno.EWOULDBLOCK: 0,
errno.EAGAIN: 0,
errno.EINTR: 0,
}
expected_socket_read_errors = tuple(tmp_dict.keys())
tmp_dict = {errno.EAGAIN: 0,
errno.EWOULDBLOCK: 0,
errno.ENOBUFS: 0,
errno.EINTR: 0,
}
expected_socket_write_errors = tuple(tmp_dict.keys())
del tmp_dict
class SizedMessageAsyncConnection(Acquisition.Explicit, asyncore.dispatcher):
__append=None # Marker indicating that we're closed
......@@ -116,7 +135,12 @@ class SizedMessageAsyncConnection(Acquisition.Explicit, asyncore.dispatcher):
join=string.join, StringType=type(''), _type=type,
_None=None):
try:
d=self.recv(8096)
except socket.error, err:
if err[0] in expected_socket_read_errors:
return
raise
if not d: return
inp=self.__inp
......@@ -160,7 +184,12 @@ class SizedMessageAsyncConnection(Acquisition.Explicit, asyncore.dispatcher):
output=self.__output
while output:
v=output[0]
try:
n=self.send(v)
except socket.error, err:
if err[0] in expected_socket_write_errors:
break # we couldn't write anything
raise
if n < len(v):
output[0]=v[n:]
break # we can't write any more
......
......@@ -85,11 +85,30 @@
"""Sized message async connections
"""
__version__ = "$Revision: 1.10 $"[11:-2]
__version__ = "$Revision: 1.11 $"[11:-2]
import asyncore, string, struct, zLOG, sys, Acquisition
import socket, errno
from zLOG import LOG, TRACE, ERROR, INFO
# Use the dictionary to make sure we get the minimum number of errno
# entries. We expect that EWOULDBLOCK == EAGAIN on most systems --
# or that only one is actually used.
tmp_dict = {errno.EWOULDBLOCK: 0,
errno.EAGAIN: 0,
errno.EINTR: 0,
}
expected_socket_read_errors = tuple(tmp_dict.keys())
tmp_dict = {errno.EAGAIN: 0,
errno.EWOULDBLOCK: 0,
errno.ENOBUFS: 0,
errno.EINTR: 0,
}
expected_socket_write_errors = tuple(tmp_dict.keys())
del tmp_dict
class SizedMessageAsyncConnection(Acquisition.Explicit, asyncore.dispatcher):
__append=None # Marker indicating that we're closed
......@@ -116,7 +135,12 @@ class SizedMessageAsyncConnection(Acquisition.Explicit, asyncore.dispatcher):
join=string.join, StringType=type(''), _type=type,
_None=None):
try:
d=self.recv(8096)
except socket.error, err:
if err[0] in expected_socket_read_errors:
return
raise
if not d: return
inp=self.__inp
......@@ -160,7 +184,12 @@ class SizedMessageAsyncConnection(Acquisition.Explicit, asyncore.dispatcher):
output=self.__output
while output:
v=output[0]
try:
n=self.send(v)
except socket.error, err:
if err[0] in expected_socket_write_errors:
break # we couldn't write anything
raise
if n < len(v):
output[0]=v[n:]
break # we can't write any more
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment