class FrameHandler(object): def __init__(self, connection): self.conn = connection self.status = status.CLOSED self._method_queue = [] self._pending_meth = None self._pending_cb = None self._msg_builder = None @property def message(self): return self._msg_builder.get_msg() @property def callback(self): return self._pending_cb def invoke_callback(self, *args, **kargs): if self._pending_cb: try: self._pending_cb(*args, **kargs) except Exception: logger.error('Error in callback for %s', self._pending_meth, exc_info=True) self._pending_cb = None def process_frame(self, frame): processor = getattr(self, 'process_'+frame.frame_type) processor(frame.payload) def process_method(self, method): if method._content: self._msg_builder = MessageBuilder(content_method=method) else: self._msg_builder = None self.handle_method(method) def process_content_header(self, ch): self._msg_builder.add_content_header(ch) def process_content_body(self, cb): # FIXME better error checking self._msg_builder.add_content_body(cb) if self._msg_builder.msg_complete: self.handle_method(self._msg_builder.content_method) def process_heartbeat(self, hb): self.conn.stream.write(HEARTBEAT) def handle_method(self, method): pending_meth = self._pending_meth if hasattr(method, 'handle'): try: method.handle(self) except AmqpError: logger.error('Error while handling %s', method, exc_info=True) self.reset() return if pending_meth and method._name.startswith(pending_meth._name): self.invoke_callback() self._flush() def send_method(self, method, callback=None, message=None): if self.status == status.CLOSED: raise AmqpStatusError('cannot send on a closed %s' % type(self).__name__) self._method_queue.append( (method, callback, message) ) if not self._pending_meth: self._flush() def _flush(self): self._pending_cb = None self._pending_meth = None while self._pending_meth is None and self._method_queue: method, callback, msg = self._method_queue.pop(0) self.write_method(method) if msg: self.write_msg(msg) if method._sync: self._pending_meth = method self._pending_cb = callback else: if callback is not None: callback() def write_method(self, method): f = from_method(method, self) self.conn.stream.write(f) def write_msg(self, msg): frames = [] frames.append(content_header_from_msg(msg, self)) frames.extend(body_frames_from_msg(msg, self)) self.conn.stream.write(''.join(frames)) def reset(self): self.status = status.CLOSED self._method_queue = [] self._pending_meth = None self._pending_cb = None self._msg_builder = None
def process_method(self, method): if method._content: self._msg_builder = MessageBuilder(content_method=method) else: self._msg_builder = None self.handle_method(method)