[Neo-report] r2035 vincent - in /trunk/neo: connection.py tests/testConnection.py

nobody at svn.erp5.org nobody at svn.erp5.org
Wed Apr 28 15:27:54 CEST 2010


Author: vincent
Date: Wed Apr 28 15:27:51 2010
New Revision: 2035

Log:
Allow a handler to send requests.

When a handler sends a request, always queue the response for handling
within the same handler, possibly delaying further a pending handler
switch.
This is for example required to properly complete identification between
master nodes, as the connecting master node might exit election phase
before receiving peer's AnswerPrimary when peer happens to be the primary.

Modified:
    trunk/neo/connection.py
    trunk/neo/tests/testConnection.py

Modified: trunk/neo/connection.py
==============================================================================
--- trunk/neo/connection.py [iso-8859-1] (original)
+++ trunk/neo/connection.py [iso-8859-1] Wed Apr 28 15:27:51 2010
@@ -77,6 +77,7 @@
         self._connection = connection
         # pending handlers and related requests
         self._pending = [[{}, handler]]
+        self._is_handling = False
 
     def clear(self):
         handler = self._pending[0][1]
@@ -92,8 +93,14 @@
     def emit(self, request, timeout):
         # register the request in the current handler
         _pending = self._pending
-        assert len(_pending) == 1 or _pending[0][0]
-        (request_dict, _) = _pending[-1]
+        if self._is_handling:
+            # If this is called while handling a packet, the response is to
+            # be excpected for the current handler...
+            (request_dict, _) = _pending[0]
+        else:
+            # ...otherwise, queue for for the latest handler
+            assert len(_pending) == 1 or _pending[0][0]
+            (request_dict, _) = _pending[-1]
         msg_id = request.getId()
         answer_class = request.getAnswerClass()
         assert answer_class is not None, "Not a request"
@@ -112,8 +119,16 @@
             result = None
         return result
 
-    @profiler_decorator
     def handle(self, packet):
+        assert not self._is_handling
+        self._is_handling = True
+        try:
+            self._handle(packet)
+        finally:
+            self._is_handling = False
+
+    @profiler_decorator
+    def _handle(self, packet):
         assert len(self._pending) == 1 or self._pending[0][0]
         PACKET_LOGGER.dispatch(self._connection, packet, 'from')
         msg_id = packet.getId()

Modified: trunk/neo/tests/testConnection.py
==============================================================================
--- trunk/neo/tests/testConnection.py [iso-8859-1] (original)
+++ trunk/neo/tests/testConnection.py [iso-8859-1] Wed Apr 28 15:27:51 2010
@@ -851,10 +851,30 @@
         self.assertFalse(self._handlers.isPending())
 
     def testEmit(self):
+        # First case, emit is called outside of a handler
         self.assertFalse(self._handlers.isPending())
         request = self._makeRequest(1)
         self._handlers.emit(request, 0)
         self.assertTrue(self._handlers.isPending())
+        # Second case, emit is called from inside a handler with a pending
+        # handler change.
+        new_handler = self._makeHandler()
+        self._handlers.setHandler(new_handler)
+        self._checkCurrentHandler(self._handler)
+        call_tracker = []
+        def packetReceived(conn, packet):
+            self._handlers.emit(self._makeRequest(2), 0)
+            call_tracker.append(True)
+        self._handler.packetReceived = packetReceived
+        self._handlers.handle(self._makeAnswer(1))
+        self.assertEqual(call_tracker, [True])
+        # Effective handler must not have changed (new request is blocking
+        # it)
+        self._checkCurrentHandler(self._handler)
+        # Handling the next response will cause the handler to change
+        delattr(self._handler, 'packetReceived')
+        self._handlers.handle(self._makeAnswer(2))
+        self._checkCurrentHandler(new_handler)
 
     def testHandleNotification(self):
         # handle with current handler





More information about the Neo-report mailing list