[Zodb-checkins] SVN: ZODB/branches/3.8/ Bug Fixed: Improved the the
ZEO client shutdown support to try to
Jim Fulton
jim at zope.com
Fri May 23 18:48:13 EDT 2008
Log message for revision 86920:
Bug Fixed: Improved the the ZEO client shutdown support to try to
avoid spurious errors on exit, especially for scripts, such as zeopack.
Changed:
U ZODB/branches/3.8/NEWS.txt
U ZODB/branches/3.8/src/ZEO/zrpc/connection.py
-=-
Modified: ZODB/branches/3.8/NEWS.txt
===================================================================
--- ZODB/branches/3.8/NEWS.txt 2008-05-23 20:27:25 UTC (rev 86919)
+++ ZODB/branches/3.8/NEWS.txt 2008-05-23 22:48:11 UTC (rev 86920)
@@ -5,6 +5,9 @@
Bugs Fixed:
+- (beta 5) Improved the the ZEO client shutdown support to try to
+ avoid spurious errors on exit, especially for scripts, such as zeopack.
+
- (beta 4) Packing failed for databases containing cross-database references.
- (beta 3) Cross-database references to databases with empty names
Modified: ZODB/branches/3.8/src/ZEO/zrpc/connection.py
===================================================================
--- ZODB/branches/3.8/src/ZEO/zrpc/connection.py 2008-05-23 20:27:25 UTC (rev 86919)
+++ ZODB/branches/3.8/src/ZEO/zrpc/connection.py 2008-05-23 22:48:11 UTC (rev 86920)
@@ -41,8 +41,16 @@
client_map = {}
client_trigger = trigger(client_map)
client_logger = logging.getLogger('ZEO.zrpc.client_loop')
-atexit.register(client_map.clear)
+client_exit_event = threading.Event()
+client_running = True
+def client_exit():
+ global client_running
+ client_running = False
+ client_trigger.pull_trigger()
+ client_exit_event.wait()
+atexit.register(client_exit)
+
def client_loop():
map = client_map
@@ -50,8 +58,11 @@
write = asyncore.write
_exception = asyncore._exception
loop_failures = 0
+ client_exit_event.clear()
+ global client_running
+ client_running = True
- while map:
+ while client_running and map:
try:
# The next two lines intentionally don't use
@@ -72,20 +83,23 @@
# case by looking for entries in r and w that
# are not in the socket map.
- if [fd for fd in r if fd not in client_map]:
+ if [fd for fd in r if fd not in map]:
continue
- if [fd for fd in w if fd not in client_map]:
+ if [fd for fd in w if fd not in map]:
continue
raise
else:
continue
+ if not client_running:
+ break
+
if not (r or w or e):
# The line intentionally doesn't use iterators. Other
# threads can close dispatchers, causeing the socket
# map to shrink.
- for obj in client_map.values():
+ for obj in map.values():
if isinstance(obj, Connection):
# Send a heartbeat message as a reply to a
# non-existent message id.
@@ -131,11 +145,14 @@
except:
map.pop(fd, None)
try:
- client_logger.critical("Couldn't close a dispatcher.",
- exc_info=sys.exc_info())
+ client_logger.critical(
+ "Couldn't close a dispatcher.",
+ exc_info=sys.exc_info())
except:
pass
+ client_exit_event.set()
+
client_thread = threading.Thread(target=client_loop)
client_thread.setDaemon(True)
client_thread.start()
More information about the Zodb-checkins
mailing list