[Neo-report] r2001 vincent - in /trunk/neo: connection.py protocol.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Mon Apr 19 11:49:34 CEST 2010
Author: vincent
Date: Mon Apr 19 11:49:33 2010
New Revision: 2001
Log:
Avoid parsing packet header multiple times when there is not enough data.
Modified:
trunk/neo/connection.py
trunk/neo/protocol.py
Modified: trunk/neo/connection.py
==============================================================================
--- trunk/neo/connection.py [iso-8859-1] (original)
+++ trunk/neo/connection.py [iso-8859-1] Mon Apr 19 11:49:33 2010
@@ -20,7 +20,7 @@
from neo import logging
from neo.locking import RLock
-from neo.protocol import PacketMalformedError, Packets
+from neo.protocol import PacketMalformedError, Packets, ParserState
from neo.connector import ConnectorException, ConnectorTryAgainException, \
ConnectorInProgressException, ConnectorConnectionRefusedException, \
ConnectorConnectionClosedException
@@ -293,6 +293,7 @@
self.uuid = None
self._queue = []
self._on_close = None
+ self._parser_state = ParserState()
event_manager.addReader(self)
def setOnClose(self, callback):
@@ -359,7 +360,7 @@
while True:
# parse a packet
try:
- packet = Packets.parse(self.read_buf)
+ packet = Packets.parse(self.read_buf, self._parser_state)
if packet is None:
break
except PacketMalformedError, msg:
Modified: trunk/neo/protocol.py
==============================================================================
--- trunk/neo/protocol.py [iso-8859-1] (original)
+++ trunk/neo/protocol.py [iso-8859-1] Mon Apr 19 11:49:33 2010
@@ -1575,6 +1575,21 @@
return (request, answer)
return request
+class ParserState(object):
+ """
+ Parser internal state.
+ To be considered opaque datatype outside of PacketRegistry.parse .
+ """
+ payload = None
+
+ def set(self, payload):
+ self.payload = payload
+
+ def get(self):
+ return self.payload
+
+ def clear(self):
+ self.payload = None
class PacketRegistry(dict):
"""
@@ -1586,28 +1601,32 @@
# load packet classes
self.update(StaticRegistry)
- def parse(self, buf):
- if len(buf) < PACKET_HEADER_SIZE:
+ def parse(self, buf, state_container):
+ state = state_container.get()
+ if state is None:
+ header = buf.read(PACKET_HEADER_SIZE)
+ if header is None:
+ return None
+ msg_id, msg_type, msg_len = unpack(PACKET_HEADER_FORMAT, header)
+ try:
+ packet_klass = self[msg_type]
+ except KeyError:
+ raise PacketMalformedError('Unknown packet type')
+ if msg_len > MAX_PACKET_SIZE:
+ raise PacketMalformedError('message too big (%d)' % msg_len)
+ if msg_len < MIN_PACKET_SIZE:
+ raise PacketMalformedError('message too small (%d)' % msg_len)
+ msg_len -= PACKET_HEADER_SIZE
+ else:
+ msg_id, packet_klass, msg_len = state
+ data = buf.read(msg_len)
+ if data is None:
+ # Not enough.
+ state_container.set((msg_id, packet_klass, msg_len))
return None
- header = buf.peek(PACKET_HEADER_SIZE)
- assert header is not None
- msg_id, msg_type, msg_len = unpack(PACKET_HEADER_FORMAT, header)
- try:
- packet_klass = self[msg_type]
- except KeyError:
- raise PacketMalformedError('Unknown packet type')
- if msg_len > MAX_PACKET_SIZE:
- raise PacketMalformedError('message too big (%d)' % msg_len)
- if msg_len < MIN_PACKET_SIZE:
- raise PacketMalformedError('message too small (%d)' % msg_len)
- if len(buf) < msg_len:
- # Not enough.
- return None
- buf.skip(PACKET_HEADER_SIZE)
- msg_len -= PACKET_HEADER_SIZE
+ if state:
+ state_container.clear()
packet = packet_klass()
- data = buf.read(msg_len)
- assert data is not None
packet.setContent(msg_id, data)
return packet
More information about the Neo-report
mailing list