[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/ Tried to make management
of the client loop more robust and added a
Jim Fulton
jim at zope.com
Tue Jul 18 18:38:45 EDT 2006
Log message for revision 69195:
Tried to make management of the client loop more robust and added a
test for it.
Changed:
U ZODB/trunk/src/ZEO/tests/testZEO.py
U ZODB/trunk/src/ZEO/zrpc/connection.py
-=-
Modified: ZODB/trunk/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/testZEO.py 2006-07-18 22:19:38 UTC (rev 69194)
+++ ZODB/trunk/src/ZEO/tests/testZEO.py 2006-07-18 22:38:44 UTC (rev 69195)
@@ -271,6 +271,43 @@
> client_timeout_count)
+class CatastrophicClientLoopFailure(
+ ZEO.tests.ConnectionTests.CommonSetupTearDown):
+ """Test what happens when the client loop falls over
+ """
+
+ def getConfig(self, path, create, read_only):
+ return """<mappingstorage 1/>"""
+
+ def checkCatastrophicClientLoopFailure(self):
+ self._storage = self.openClientStorage()
+
+ class Evil:
+ def writable(self):
+ raise SystemError("I'm evil")
+
+ log = []
+ ZEO.zrpc.connection.client_logger.critical = (
+ lambda m, *a, **kw: log.append((m % a, kw))
+ )
+
+ ZEO.zrpc.connection.client_map[None] = Evil()
+
+ try:
+ ZEO.zrpc.connection.client_trigger.pull_trigger()
+ except DisconnectedError:
+ pass
+
+ time.sleep(.1)
+ self.failIf(self._storage.is_connected())
+ self.assertEqual(len(ZEO.zrpc.connection.client_map), 1)
+ del ZEO.zrpc.connection.client_logger.critical
+ self.assertEqual(log[0][0], 'The ZEO cient loop failed.')
+ self.assert_('exc_info' in log[0][1])
+ self.assertEqual(log[1][0], "Couldn't close a dispatcher.")
+ self.assert_('exc_info' in log[1][1])
+
+
class DemoStorageWrappedAroundClientStorage(DemoStorageWrappedBase):
def getConfig(self):
@@ -307,6 +344,7 @@
MappingStorageTests,
DemoStorageWrappedAroundClientStorage,
HeartbeatTests,
+ CatastrophicClientLoopFailure,
]
def test_suite():
Modified: ZODB/trunk/src/ZEO/zrpc/connection.py
===================================================================
--- ZODB/trunk/src/ZEO/zrpc/connection.py 2006-07-18 22:19:38 UTC (rev 69194)
+++ ZODB/trunk/src/ZEO/zrpc/connection.py 2006-07-18 22:38:44 UTC (rev 69195)
@@ -34,19 +34,19 @@
##############################################################################
# Dedicated Client select loop:
+client_timeout = 30.0
+client_timeout_count = 0 # for testing
client_map = {}
client_trigger = trigger(client_map)
-client_timeout = 30.0
-client_timeout_count = 0 # for testing
+client_logger = logging.getLogger('ZEO.zrpc.client_loop')
def client_loop():
map = client_map
- logger = logging.getLogger('ZEO.zrpc.client_loop')
- logger.addHandler(logging.StreamHandler())
read = asyncore.read
write = asyncore.write
_exception = asyncore._exception
+ loop_failures = 0
while map:
try:
@@ -106,8 +106,17 @@
_exception(obj)
except:
- logger.exception('poll failure')
- raise
+ client_logger.critical('The ZEO cient loop failed.',
+ exc_info=sys.exc_info())
+ for fd, obj in map.items():
+ if obj is client_trigger:
+ continue
+ try:
+ obj.mgr.client.close()
+ except:
+ map.pop(fd, None)
+ client_logger.critical("Couldn't close a dispatcher.",
+ exc_info=sys.exc_info())
client_thread = threading.Thread(target=client_loop)
client_thread.setDaemon(True)
More information about the Zodb-checkins
mailing list