[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