[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