SVN: ZODB/trunk/src/ZEO/ Bug fix: the ConnectionManager could hang if its ConnectThread died

Patrick Strawderman <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <20100909151057.DB1C2941EF__47814.3783206635$1284045065$gmane$org@cvs.zope.org>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.