[Zodb-checkins] CVS: ZODB3/ZEO/zrpc - connection.py:1.38.18.1

Barry Warsaw barry@wooz.org
Fri, 1 Nov 2002 15:43:28 -0500


Update of /cvs-repository/ZODB3/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv29445

Modified Files:
      Tag: ZODB3-deadlock-debug-branch
	connection.py 
Log Message:
Moderately tested patch to avoid EPIPE errors when pulling the async
trigger.  Modeled after WakeUp() in Zope's ZServer/PubCore/ZEvents.py.

It's only moderately tested because I couldn't reproduce the
originally reported bug, so I don't know for sure that this fixes the
problem.  Seems somewhat likely.

Note: the _pull_trigger() approach of trying again 10 times might not
be helpful.  Even with this, if the EPIPE is raised, re-pulling the
trigger doesn't seem to help avoid a delay in Zope responding.  That
could be a consequence of the way I artificially raised EPIPE in my
limited testing (I did that in trigger.py's pull_trigger() by just
raising EPIPE every random Nth call).


=== ZODB3/ZEO/zrpc/connection.py 1.38 => 1.38.18.1 ===
--- ZODB3/ZEO/zrpc/connection.py:1.38	Sat Sep 28 23:24:17 2002
+++ ZODB3/ZEO/zrpc/connection.py	Fri Nov  1 15:43:27 2002
@@ -348,13 +348,24 @@
         else:
             return 0
 
+    def _pull_trigger(self, tryagain=10):
+        try:
+            self.trigger.pull_trigger()
+        except OSError, e:
+            if e[0] != errno.EPIPE:
+                raise
+            self.trigger.close()
+            self.trigger = trigger()
+            if tryagain > 0:
+                self._pull_trigger(tryagain=tryagain-1)
+
     def wait(self, msgid):
         """Invoke asyncore mainloop and wait for reply."""
         if __debug__:
             log("wait(%d), async=%d" % (msgid, self.is_async()),
                 level=zLOG.TRACE)
         if self.is_async():
-            self.trigger.pull_trigger()
+            self._pull_trigger()
 
         # Delay used when we call asyncore.poll() directly.
         # Start with a 1 msec delay, double until 1 sec.
@@ -398,7 +409,7 @@
         if __debug__:
             log("poll(), async=%d" % self.is_async(), level=zLOG.TRACE)
         if self.is_async():
-            self.trigger.pull_trigger()
+            self._pull_trigger()
         else:
             asyncore.poll(0.0, self._map)