[Zodb-checkins] SVN: ZODB/trunk/src/ Fix: https://bugs.launchpad.net/zodb/+bug/135108

Jim Fulton jim at zope.com
Tue May 4 12:36:52 EDT 2010


Log message for revision 111931:
  Fix: https://bugs.launchpad.net/zodb/+bug/135108
  

Changed:
  U   ZODB/trunk/src/CHANGES.txt
  U   ZODB/trunk/src/ZEO/tests/testZEO.py
  U   ZODB/trunk/src/ZEO/zrpc/server.py

-=-
Modified: ZODB/trunk/src/CHANGES.txt
===================================================================
--- ZODB/trunk/src/CHANGES.txt	2010-05-04 16:17:58 UTC (rev 111930)
+++ ZODB/trunk/src/CHANGES.txt	2010-05-04 16:36:52 UTC (rev 111931)
@@ -62,6 +62,15 @@
 
 - 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)
 =====================
 

Modified: ZODB/trunk/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/testZEO.py	2010-05-04 16:17:58 UTC (rev 111930)
+++ ZODB/trunk/src/ZEO/tests/testZEO.py	2010-05-04 16:36:52 UTC (rev 111931)
@@ -1338,6 +1338,34 @@
     class MultiprocessingTests(unittest.TestCase):
         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 = [
     BlobAdaptedFileStorageTests, BlobWritableCacheTests,
     DemoStorageTests, FileStorageTests, MappingStorageTests,

Modified: ZODB/trunk/src/ZEO/zrpc/server.py
===================================================================
--- ZODB/trunk/src/ZEO/zrpc/server.py	2010-05-04 16:17:58 UTC (rev 111930)
+++ ZODB/trunk/src/ZEO/zrpc/server.py	2010-05-04 16:36:52 UTC (rev 111931)
@@ -17,6 +17,7 @@
 
 from ZEO.zrpc.connection import Connection
 from ZEO.zrpc.log import log
+import ZEO.zrpc.log
 import logging
 
 # Export the main asyncore loop
@@ -54,5 +55,23 @@
         except socket.error, msg:
             log("accepted failed: %s" % msg)
             return
-        c = self.factory(sock, addr)
-        log("connect from %s: %s" % (repr(addr), c))
+
+        # 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)
+        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))



More information about the Zodb-checkins mailing list