[Neo-report] r2641 vincent - in /trunk/neo: client/ lib/ tests/client/

nobody at svn.erp5.org nobody at svn.erp5.org
Tue Jan 25 11:59:13 CET 2011


Author: vincent
Date: Tue Jan 25 11:59:13 2011
New Revision: 2641

Log:
Don't wait for all answers when aborting.

Instead, forget them at dispatcher level, and empty queue (in case
answers were received but not handled yet).

Modified:
    trunk/neo/client/app.py
    trunk/neo/lib/dispatcher.py
    trunk/neo/tests/client/testClientApp.py

Modified: trunk/neo/client/app.py
==============================================================================
--- trunk/neo/client/app.py [iso-8859-1] (original)
+++ trunk/neo/client/app.py [iso-8859-1] Tue Jan 25 11:59:13 2011
@@ -815,22 +815,13 @@ class Application(object):
                     'storage node %r of abortion, ignoring.',
                     conn, exc_info=1)
         self._getMasterConnection().notify(p)
-
-        # Just wait for responses to arrive. If any leads to an exception,
-        # log it and continue: we *must* eat all answers to not disturb the
-        # next transaction.
         queue = self.local_var.queue
-        pending = self.dispatcher.pending
-        _waitAnyMessage = self._waitAnyMessage
-        while pending(queue):
+        self.dispatcher.forget_queue(queue)
+        while True:
             try:
-                _waitAnyMessage()
-            except:
-                neo.lib.logging.error(
-                    'Exception in tpc_abort while' \
-                    'handling pending answers, ignoring.',
-                    exc_info=1)
-
+                queue.get(block=False)
+            except Empty:
+                break
         self.local_var.clear()
 
     @profiler_decorator

Modified: trunk/neo/lib/dispatcher.py
==============================================================================
--- trunk/neo/lib/dispatcher.py [iso-8859-1] (original)
+++ trunk/neo/lib/dispatcher.py [iso-8859-1] Tue Jan 25 11:59:13 2011
@@ -131,6 +131,26 @@ class Dispatcher:
         message_table[msg_id] = NOBODY
         return queue
 
+    @giant_lock
+    @profiler_decorator
+    def forget_queue(self, queue):
+        """
+        Forget all pending messages for given queue.
+        Actually makes them "expected by nobody", so we know we can ignore
+        them, and not detect it as an error.
+        """
+        # XXX: expensive lookup: we iterate over the whole dict
+        found = 0
+        for message_table in self.message_table.itervalues():
+            for msg_id, t_queue in message_table.iteritems():
+                if queue is t_queue:
+                    found += 1
+                    message_table[msg_id] = NOBODY
+        refcount = self.queue_dict.pop(id(queue), 0)
+        if refcount != found:
+            raise ValueError('We hit a refcount bug: %s queue uses ' \
+                'expected, %s found' % (refcount, found))
+
     @profiler_decorator
     def registered(self, conn):
         """Check if a connection is registered into message table."""

Modified: trunk/neo/tests/client/testClientApp.py
==============================================================================
--- trunk/neo/tests/client/testClientApp.py [iso-8859-1] (original)
+++ trunk/neo/tests/client/testClientApp.py [iso-8859-1] Tue Jan 25 11:59:13 2011
@@ -621,6 +621,9 @@ class ClientApplicationTests(NeoUnitTest
         class Dispatcher(object):
             def pending(self, queue):
                 return not queue.empty()
+
+            def forget_queue(self, queue):
+                pass
         app.dispatcher = Dispatcher()
         # conflict occurs on storage 2
         app.store(oid1, tid, 'DATA', None, txn)




More information about the Neo-report mailing list