[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/ Bug fix: the ConnectionManager could hang if its ConnectThread died

Patrick Strawderman patrick at zope.com
Thu Sep 9 11:10:57 EDT 2010


Log message for revision 116272:
  Bug fix: the ConnectionManager could hang if its ConnectThread died
  without setting the connection.
  

Changed:
  U   ZODB/trunk/src/ZEO/tests/testZEO.py
  U   ZODB/trunk/src/ZEO/zrpc/client.py

-=-
Modified: ZODB/trunk/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/testZEO.py	2010-09-09 14:41:16 UTC (rev 116271)
+++ ZODB/trunk/src/ZEO/tests/testZEO.py	2010-09-09 15:10:57 UTC (rev 116272)
@@ -1519,7 +1519,33 @@
     >>> db.close()
 
     """
+def sync_connect_doesnt_hang():
+    r"""
+    >>> import threading
+    >>> import ZEO.zrpc.client
+    >>> ConnectThread = ZEO.zrpc.client.ConnectThread
+    >>> ZEO.zrpc.client.ConnectThread = lambda *a, **kw: threading.Thread()
 
+    >>> class CM(ZEO.zrpc.client.ConnectionManager):
+    ...     sync_wait = 1
+    ...     _start_asyncore_loop = lambda self: None
+    >>> cm = CM('', object())
+
+    Calling connect results in an exception being raised, instead of hanging
+    indefinitely when the thread dies without setting up the connection.
+
+    >>> cm.connect(sync=1)
+    Traceback (most recent call last):
+    ...
+    AssertionError
+
+    >>> cm.thread.isAlive()
+    False
+    >>> ZEO.zrpc.client.ConnectThread = ConnectThread
+
+    """
+
+
 slow_test_classes = [
     BlobAdaptedFileStorageTests, BlobWritableCacheTests,
     MappingStorageTests, DemoStorageTests,
@@ -1535,7 +1561,7 @@
 
     class StorageServerStubClass(ZEO.ServerStub.StorageServer):
 
-        # Wait for abort for the benefit of blob_transacton.txt
+        # Wait for abort for the benefit of blob_transaction.txt
         def tpc_abort(self, id):
             self.rpc.call('tpc_abort', id)
 

Modified: ZODB/trunk/src/ZEO/zrpc/client.py
===================================================================
--- ZODB/trunk/src/ZEO/zrpc/client.py	2010-09-09 14:41:16 UTC (rev 116271)
+++ ZODB/trunk/src/ZEO/zrpc/client.py	2010-09-09 15:10:57 UTC (rev 116272)
@@ -131,6 +131,8 @@
 class ConnectionManager(object):
     """Keeps a connection up over time"""
 
+    sync_wait = 30
+
     def __init__(self, addrs, client, tmin=1, tmax=180):
         self.client = client
         self._start_asyncore_loop()
@@ -273,14 +275,13 @@
                 t.setDaemon(1)
                 t.start()
             if sync:
-                while self.connection is None:
-                    self.cond.wait(30)
+                while self.connection is None and t.isAlive():
+                    self.cond.wait(self.sync_wait)
                     if self.connection is None:
                         log("CM.connect(sync=1): still waiting...")
+                assert self.connection is not None
         finally:
             self.cond.release()
-        if sync:
-            assert self.connection is not None
 
     def connect_done(self, conn, preferred):
         # Called by ConnectWrapper.notify_client() after notifying the client



More information about the Zodb-checkins mailing list