async def _on_history_response(self, message: aio_pika.Message): with message.process(requeue=True): body = message.body from_token = message.app_id correlation_id = message.correlation_id request_duration = float(message.headers.get("x-request-duration", "-1")) logger.debug( "received message from {}, correlation id: {}, reply_to: {}", from_token, correlation_id, message.reply_to, ) history_response_pb = history_pb2.HistoryResponse() history_response_pb.ParseFromString(body) history_response = HistoryResponse(history_response_pb, request_duration) logger.debug("message is an history response") try: future = self._request_futures[correlation_id] future.set_result(history_response) except (KeyError, asyncio.InvalidStateError): logger.error( "received history response with unknown correlation id {} " "from {}", correlation_id, from_token, ) return
async def _on_management_message(self, message: aio_pika.Message): """ :param message: This is either an RPC or an RPC response """ with message.process(requeue=True): time_begin = timer() body = message.body.decode() from_token = message.app_id correlation_id = message.correlation_id logger.info( "received message from {}, correlation id: {}, reply_to: {}, length: {}\n{}", from_token, correlation_id, message.reply_to, len(body), textwrap.shorten(body, width=self.LOG_MAX_WIDTH), ) arguments = json.loads(body) arguments["from_token"] = from_token function = arguments.get("function") if function is not None: logger.debug("message is an RPC") try: response = await self.rpc_dispatch(**arguments) except Exception as e: logger.error( "error handling RPC {} ({}): {}", function, type(e), traceback.format_exc(), ) response = {"error": str(e)} if response is None: response = dict() duration = timer() - time_begin body = json.dumps(response) logger.info( "rpc response to {}, correlation id: {}, length: {}, time: {} s\n{}", from_token, correlation_id, len(body), duration, textwrap.shorten(body, width=self.LOG_MAX_WIDTH), ) await self._management_connection_watchdog.established() try: await self._management_channel.default_exchange.publish( aio_pika.Message( body=body.encode(), correlation_id=correlation_id, content_type="application/json", app_id=self.token, ), routing_key=message.reply_to, ) except ChannelInvalidStateError as e: errmsg = ( "Failed to reply to {message.reply_to} for RPC {function!r}" ) logger.error("{}: {}", errmsg, e) raise RpcReplyError(errmsg) from e else: logger.debug("message is an RPC response") try: handler, cleanup = self._rpc_response_handlers[ correlation_id] except KeyError: logger.error( "received RPC response with unknown correlation id {} from {}", correlation_id, from_token, ) # We do not throw here, no requeue for this! return if cleanup: del self._rpc_response_handlers[correlation_id] if not handler: return # Allow simple handlers that are not coroutines # But only None to not get any confusion r = handler(**arguments) if r is not None: await r