Commit 88b1c803 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Delay handler until pending requests as over.

When a new handler is applied on a connection, register a special packet
in the request queue to set the handler when all current requests receive
their answer.

git-svn-id: https://svn.erp5.org/repos/neo/trunk@1706 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 7c7abfc0
...@@ -30,6 +30,8 @@ from neo.logger import PACKET_LOGGER ...@@ -30,6 +30,8 @@ from neo.logger import PACKET_LOGGER
from neo import attributeTracker from neo import attributeTracker
APPLY_HANDLER = object()
def not_closed(func): def not_closed(func):
def decorator(self, *args, **kw): def decorator(self, *args, **kw):
if self.connector is None: if self.connector is None:
...@@ -199,12 +201,24 @@ class Connection(BaseConnection): ...@@ -199,12 +201,24 @@ class Connection(BaseConnection):
self.uuid = None self.uuid = None
self._queue = [] self._queue = []
self._expected = deque() self._expected = deque()
self._next_handler = None
BaseConnection.__init__(self, event_manager, handler, BaseConnection.__init__(self, event_manager, handler,
connector = connector, addr = addr, connector = connector, addr = addr,
connector_handler = connector_handler) connector_handler = connector_handler)
if connector is not None: if connector is not None:
event_manager.addReader(self) event_manager.addReader(self)
def setHandler(self, handler):
assert self._next_handler is None
if self.hasPendingRequests():
logging.debug('Delaying: %s -> %s after %s',
self.handler.__class__.__name__, handler.__class__.__name__,
list(self._expected))
self._expected.append(APPLY_HANDLER)
self._next_handler = handler
else:
self.handler = handler
def isAborted(self): def isAborted(self):
return self.aborted return self.aborted
...@@ -307,11 +321,18 @@ class Connection(BaseConnection): ...@@ -307,11 +321,18 @@ class Connection(BaseConnection):
""" """
Process a pending packet. Process a pending packet.
""" """
# check out packet and check if it's and expected answer
packet = self._queue.pop(0) packet = self._queue.pop(0)
if packet.isResponse(): if packet.isResponse():
request = None request = None
if self._expected: if self._expected:
request = self._expected.popleft() request = self._expected.popleft()
if request is APPLY_HANDLER:
logging.debug('Apply handler %s',
self._next_handler.__class__.__name__)
self.handler = self._next_handler
self._next_handler = None
return
if not request or not request.answerMatch(packet): if not request or not request.answerMatch(packet):
req_info = ('', '') req_info = ('', '')
if request is not None: if request is not None:
...@@ -319,6 +340,8 @@ class Connection(BaseConnection): ...@@ -319,6 +340,8 @@ class Connection(BaseConnection):
rep_info = (packet.getId(), packet.__class__) rep_info = (packet.getId(), packet.__class__)
logging.warning('Unexpected answer: %s:%s %s:%s' % logging.warning('Unexpected answer: %s:%s %s:%s' %
(rep_info + req_info)) (rep_info + req_info))
# process packet
PACKET_LOGGER.dispatch(self, packet, 'from') PACKET_LOGGER.dispatch(self, packet, 'from')
self.handler.packetReceived(self, packet) self.handler.packetReceived(self, packet)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment