Commit cfe16277 authored by Jim Fulton's avatar Jim Fulton
parent 10bf4413
...@@ -62,6 +62,15 @@ Bugs Fixed ...@@ -62,6 +62,15 @@ Bugs Fixed
- Fixed some problems in ZEO server commit lock management. - Fixed some problems in ZEO server commit lock management.
- On Mac OS X, clients that connected and disconnected quickly could
cause a ZEO server to stop accepting connections, due to a failure
to catch errors in the initial part of the connection process.
The failure to properly handle exceptions while accepting
connections is potentially problematic on other platforms.
Fixes: https://bugs.launchpad.net/zodb/+bug/135108
3.10.0a1 (2010-02-08) 3.10.0a1 (2010-02-08)
===================== =====================
......
...@@ -1338,6 +1338,34 @@ else: ...@@ -1338,6 +1338,34 @@ else:
class MultiprocessingTests(unittest.TestCase): class MultiprocessingTests(unittest.TestCase):
pass pass
def quick_close_doesnt_kill_server():
r"""
Start a server:
>>> addr, _ = start_server()
Now connect and immediately disconnect. This caused the server to
die in the past:
>>> import socket, struct
>>> for i in range(5):
... s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
... s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
... struct.pack('ii', 1, 0))
... s.connect(addr)
... s.close()
Now we should be able to connect as normal:
>>> db = ZEO.DB(addr)
>>> db.storage.is_connected()
True
>>> db.close()
"""
slow_test_classes = [ slow_test_classes = [
BlobAdaptedFileStorageTests, BlobWritableCacheTests, BlobAdaptedFileStorageTests, BlobWritableCacheTests,
DemoStorageTests, FileStorageTests, MappingStorageTests, DemoStorageTests, FileStorageTests, MappingStorageTests,
......
...@@ -17,6 +17,7 @@ import types ...@@ -17,6 +17,7 @@ import types
from ZEO.zrpc.connection import Connection from ZEO.zrpc.connection import Connection
from ZEO.zrpc.log import log from ZEO.zrpc.log import log
import ZEO.zrpc.log
import logging import logging
# Export the main asyncore loop # Export the main asyncore loop
...@@ -54,5 +55,23 @@ class Dispatcher(asyncore.dispatcher): ...@@ -54,5 +55,23 @@ class Dispatcher(asyncore.dispatcher):
except socket.error, msg: except socket.error, msg:
log("accepted failed: %s" % msg) log("accepted failed: %s" % msg)
return return
# We could short-circuit the attempt below in some edge cases
# and avoid a log message by checking for addr being None.
# Unfortunately, our test for the code below,
# quick_close_doesnt_kill_server, causes addr to be None and
# we'd have to write a test for the non-None case, which is
# *even* harder to provoke. :/ So we'll leave things as they
# are for now.
# It might be better to check whether the socket has been
# closed, but I don't see a way to do that. :(
try:
c = self.factory(sock, addr) c = self.factory(sock, addr)
except:
if sock.fileno() in asyncore.socket_map:
del asyncore.socket_map[sock.fileno()]
ZEO.zrpc.log.logger.exception("Error in handle_accept")
else:
log("connect from %s: %s" % (repr(addr), c)) log("connect from %s: %s" % (repr(addr), c))
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