[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/ Changed close to use the asyncore thread to try to avoid a race and
Jim Fulton
jim at zope.com
Tue Dec 22 15:28:07 EST 2009
Log message for revision 106930:
Changed close to use the asyncore thread to try to avoid a race and
breaking the client loop.
Changed:
U ZODB/trunk/src/ZEO/ClientStorage.py
U ZODB/trunk/src/ZEO/tests/testZEO.py
-=-
Modified: ZODB/trunk/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/trunk/src/ZEO/ClientStorage.py 2009-12-22 20:28:05 UTC (rev 106929)
+++ ZODB/trunk/src/ZEO/ClientStorage.py 2009-12-22 20:28:07 UTC (rev 106930)
@@ -442,11 +442,20 @@
logger.info("%s Waiting for cache verification to finish",
self.__name__)
- def close(self):
- """Storage API: finalize the storage, releasing external resources."""
+ def close(self, kill=False):
+ "Storage API: finalize the storage, releasing external resources."
if self._rpc_mgr is not None:
self._rpc_mgr.close()
self._rpc_mgr = None
+
+ if (self._connection is not None) and not kill:
+ event = threading.Event()
+ self._connection.trigger.pull_trigger(lambda: self._close(event))
+ event.wait(9)
+ else:
+ self._close()
+
+ def _close(self, event=None):
if self._connection is not None:
self._connection.register_object(None) # Don't call me!
self._connection.close()
@@ -462,6 +471,9 @@
if self._check_blob_size_thread is not None:
self._check_blob_size_thread.join()
+ if event is not None:
+ event.set()
+
_check_blob_size_thread = None
def _check_blob_size(self, bytes=None):
if self._blob_cache_size is None:
Modified: ZODB/trunk/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/testZEO.py 2009-12-22 20:28:05 UTC (rev 106929)
+++ ZODB/trunk/src/ZEO/tests/testZEO.py 2009-12-22 20:28:07 UTC (rev 106930)
@@ -951,6 +951,8 @@
... pass
... def close(self):
... print 'connection closed'
+ ... trigger = property(lambda self: self)
+ ... pull_trigger = lambda self, func: func()
>>> class ConnectionManager:
... def __init__(self, addr, client, tmin, tmax):
@@ -1228,6 +1230,35 @@
testing exit immediately
"""
+def close_client_storage_w_invalidations():
+ r"""
+Invalidations could cause errors when closing client storages,
+
+ >>> addr, _ = start_server()
+ >>> writing = threading.Event()
+ >>> def mad_write_thread():
+ ... global writing
+ ... conn = ZEO.connection(addr)
+ ... writing.set()
+ ... while writing.isSet():
+ ... conn.root.x = 1
+ ... transaction.commit()
+ ... conn.close()
+
+ >>> thread = threading.Thread(target=mad_write_thread)
+ >>> thread.setDaemon(True)
+ >>> thread.start()
+ >>> writing.wait()
+ >>> time.sleep(.01)
+ >>> for i in range(10):
+ ... conn = ZEO.connection(addr)
+ ... _ = conn._storage.load('\0'*8)
+ ... conn.close()
+
+ >>> writing.clear()
+ >>> thread.join(1)
+ """
+
slow_test_classes = [
BlobAdaptedFileStorageTests, BlobWritableCacheTests,
DemoStorageTests, FileStorageTests, MappingStorageTests,
More information about the Zodb-checkins
mailing list