Beispiel #1
0
    async def call(self,
                   method_name,
                   kwargs: dict = None,
                   *,
                   expiration: int = None,
                   priority: int = 5,
                   delivery_mode: DeliveryMode = RPC.DELIVERY_MODE):
        with tracer.trace(method_name, service='rabbitmq'):
            future = self.create_future()

            headers = {'From': self.result_queue.name}
            context = current_trace_context()
            self.DDTRACE_PROPAGATOR.inject(context, headers)

            message = Message(body=self.serialize(kwargs or {}),
                              type=RPCMessageTypes.call.value,
                              timestamp=time.time(),
                              priority=priority,
                              correlation_id=id(future),
                              delivery_mode=delivery_mode,
                              reply_to=self.result_queue.name,
                              headers=headers)

            if expiration is not None:
                message.expiration = expiration

            await self.channel.default_exchange.publish(
                message, routing_key=method_name, mandatory=True)
            return await future
Beispiel #2
0
    async def call(
        self,
        method_name,
        kwargs: Optional[Dict[Hashable, Any]] = None,
        *,
        expiration: Optional[int] = None,
        priority: int = 5,
        delivery_mode: DeliveryMode = DELIVERY_MODE
    ):
        """ Call remote method and awaiting result.

        :param method_name: Name of method
        :param kwargs: Methos kwargs
        :param expiration:
            If not `None` messages which staying in queue longer
            will be returned and :class:`asyncio.TimeoutError` will be raised.
        :param priority: Message priority
        :param delivery_mode: Call message delivery mode
        :raises asyncio.TimeoutError: when message expired
        :raises CancelledError: when called :func:`RPC.cancel`
        :raises RuntimeError: internal error
        """

        future = self.create_future()

        message = Message(
            body=self.serialize(kwargs or {}),
            type=RPCMessageTypes.call.value,
            timestamp=time.time(),
            priority=priority,
            correlation_id=id(future),
            delivery_mode=delivery_mode,
            reply_to=self.result_queue.name,
            headers={"From": self.result_queue.name},
        )

        if expiration is not None:
            message.expiration = expiration

        log.debug("Publishing calls for %s(%r)", method_name, kwargs)
        await self.channel.default_exchange.publish(
            message, routing_key=method_name, mandatory=True,
        )

        log.debug("Waiting RPC result for %s(%r)", method_name, kwargs)
        return await future
Beispiel #3
0
 async def rpc_call_async(
     self,
     method: str,
     kwargs: dict,
     expiration: int = 10,
     priority: RPCCallPriority = RPCCallPriority.MEDIUM,
 ) -> bool:
     message = Message(
         body=self.rpc.serialize(kwargs or {}),
         type=RPCMessageTypes.call.value,
         timestamp=time(),
         priority=priority.value,
         delivery_mode=self.rpc.DELIVERY_MODE,
     )
     if expiration is not None:
         message.expiration = expiration
     response = await self.channel.default_exchange.publish(
         message,
         routing_key=method,
         mandatory=True,
     )
     return isinstance(response, Basic.Ack)
Beispiel #4
0
    def call(self, method_name, kwargs: dict=None, *, expiration: int = None,
             priority: int = 128, delivery_mode: DeliveryMode = DeliveryMode.NOT_PERSISTENT):

        """ Call remote method and awaiting result.

        :param method_name: Name of method
        :param kwargs: Methos kwargs
        :param expiration: If not `None` messages which staying in queue longer
                           will be returned and :class:`asyncio.TimeoutError` will be raised.
        :param priority: Message priority
        :param delivery_mode: Call message delivery mode
        :raises asyncio.TimeoutError: when message expired
        :raises CancelledError: when called :func:`RPC.cancel`
        :raises RuntimeError: internal error
        """

        future = self.create_future()

        message = Message(
            body=self.serialize(kwargs or {}),
            type='call',
            timestamp=time.time(),
            priority=priority,
            correlation_id=id(future),
            delivery_mode=delivery_mode,
            reply_to=self.result_queue.name,
            headers={
                'From': self.result_queue.name
            }
        )

        if expiration is not None:
            message.expiration = expiration

        yield from self.channel.default_exchange.publish(
            message, routing_key=method_name, mandatory=True
        )

        return (yield from future)
Beispiel #5
0
    async def request(
        self,
        data: Any,
        *,
        service_name: str = None,
        expiration: int = None,
        delivery_mode: DeliveryMode = DeliveryMode.NOT_PERSISTENT,
    ) -> asyncio.Future:
        """ Send a message to a service and wait for a response.

        :param data: The message data to transfer.

        :param expiration: An optional value representing the number of
          seconds that a message can remain in a queue before being returned
          and a timeout exception (:class:`asyncio.TimeoutError`) is raised.

        :param delivery_mode: Request message delivery mode. Default is
          not-persistent.

        :raises asyncio.TimeoutError: When message expires before being handled.

        :raises CancelledError: when called :func:`RPC.cancel`

        :raises Exception: internal error
        """
        service_name = service_name if service_name else self.service_name

        correlation_id, future = self.create_future()

        headers = {}  # type: Dict[str, str]

        # An exception may be raised here if the message can not be serialized.
        payload, content_type, content_encoding = utils.encode_payload(
            data,
            content_type=self.serialization,
            compression=self.compression,
            headers=headers,
        )

        assert self.response_queue is not None

        # Add a 'From' entry to message headers which will be used to route an
        # expired message to the dead letter exchange queue.
        headers["From"] = self.response_queue.name

        message = Message(
            body=payload,
            content_type=content_type,
            content_encoding=content_encoding,
            timestamp=time.time(),
            correlation_id=correlation_id,
            delivery_mode=delivery_mode,
            reply_to=self.response_queue.name,
            headers=headers,
        )

        if expiration is not None:
            message.expiration = expiration

        logger.debug(
            f"Sending request to {service_name} with correlation_id: {correlation_id}"
        )

        assert self.exchange is not None
        await self.exchange.publish(
            message,
            routing_key=service_name,
            mandatory=True,  # report error if no queues are actively consuming
        )

        logger.debug(f"Waiting for response from {service_name}")
        return await future