Commit 64ea9275 authored by Jim Fulton's avatar Jim Fulton

Bug fix: the ConnectionManager could hang if its ConnectThread died

without setting the connection.
parent 8c10da5a
......@@ -1326,6 +1326,32 @@ def quick_close_doesnt_kill_server():
>>> 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,
......@@ -1341,7 +1367,7 @@ class ServerManagingClientStorage(ClientStorage):
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)
......
......@@ -29,6 +29,8 @@ from ZEO.zrpc.connection import ManagedClientConnection, start_client_thread
class ConnectionManager(object):
"""Keeps a connection up over time"""
sync_wait = 30
def __init__(self, addrs, client, tmin=1, tmax=180):
start_client_thread()
self.addrlist = self._parse_addrs(addrs)
......@@ -148,14 +150,13 @@ class ConnectionManager(object):
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
......
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