You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.6 KiB
Python

from typing import Callable, Generic, Optional, TypeVar
from amqpstorm import Channel
from amqpworker.easyqueue.connection import AMQPConnection
from amqpworker.easyqueue.exceptions import UndecodableMessageException
T = TypeVar("T")
class AMQPMessage(Generic[T]):
__slots__ = (
"connection",
"channel",
"queue_name",
"serialized_data",
"delivery_tag",
"_properties",
"_deserialization_method",
"_deserialized_data",
"_queue",
)
def __init__(
self,
connection: AMQPConnection,
channel: Channel,
queue_name: str,
serialized_data: bytes,
delivery_tag: int,
properties: dict,
deserialization_method: Callable[[bytes], T],
queue,
) -> None:
self.queue_name = queue_name
self.serialized_data = serialized_data
self.delivery_tag = delivery_tag
self.connection = connection
self.channel = channel
self._properties = properties
self._deserialization_method = deserialization_method
self._deserialized_data: Optional[T] = None
self._queue = queue
@property
def deserialized_data(self) -> T:
if self._deserialized_data:
return self._deserialized_data
try:
self._deserialized_data = self._deserialization_method(
self.serialized_data
)
except ValueError as e:
raise UndecodableMessageException(
"msg couldn't be decoded as JSON"
) from e
return self._deserialized_data
def __eq__(self, other):
if not isinstance(other, self.__class__):
return False
for attr in self.__slots__:
if attr.startswith("__"):
continue
if getattr(self, attr) != getattr(other, attr):
return False
return True
def ack(self):
return self.channel.basic.ack(self.delivery_tag)
def reject(self, requeue=False):
return self.channel.basic.reject(
delivery_tag=self.delivery_tag, requeue=requeue
)
def requeue(self):
self.channel.basic.ack(self.delivery_tag)
self.channel.basic.publish(body=self.serialized_data,
routing_key=self.queue_name,
properties=self._properties,
mandatory=False,
immediate=False)