feat/#63 - add iterator instead of RabbitMQ callback
Unit test coverage / pytest (pull_request) Failing after 1m49s
Build and Publish Docker Image / build-and-push (push) Successful in 2m29s
Unit test coverage / pytest (push) Failing after 1m45s
/ build-and-push (push) Successful in 1m52s
CI for pypl publish / publish-lib (push) Successful in 1m44s
Unit test coverage / pytest (pull_request) Failing after 1m49s
Build and Publish Docker Image / build-and-push (push) Successful in 2m29s
Unit test coverage / pytest (push) Failing after 1m45s
/ build-and-push (push) Successful in 1m52s
CI for pypl publish / publish-lib (push) Successful in 1m44s
This commit is contained in:
@@ -4,7 +4,7 @@ import logging.config
|
||||
import os
|
||||
from asyncio import Future
|
||||
from threading import Thread
|
||||
from typing import Optional
|
||||
from typing import AsyncIterator, Optional
|
||||
|
||||
from aio_pika.abc import AbstractRobustExchange
|
||||
|
||||
@@ -12,7 +12,7 @@ from amqp.adapter.amq_route_factory import AMQRouteFactory
|
||||
from amqp.adapter.backpressure_handler import BackpressureHandler
|
||||
from amqp.adapter.consul_global_id_generator import get_unique_instance_id
|
||||
from amqp.adapter.data_message_factory import DataMessageFactory
|
||||
from amqp.adapter.logging_utils import logging_info, logging_warning
|
||||
from amqp.adapter.logging_utils import logging_error, logging_info, logging_warning
|
||||
from amqp.adapter.service_message_factory import ServiceMessageFactory
|
||||
from amqp.config.amq_configuration import AMQConfiguration
|
||||
from amqp.model.model import AMQRoute, DataMessage
|
||||
@@ -65,6 +65,7 @@ class AMQService:
|
||||
self.backpressure_thread: Optional[Thread] = None
|
||||
self.backpressure_handler: Optional[BackpressureHandler] = None
|
||||
self.maximum_availability = -1
|
||||
self.future: Future = asyncio.Future()
|
||||
|
||||
# =======================================================================
|
||||
# =======================================================================
|
||||
@@ -82,6 +83,7 @@ class AMQService:
|
||||
logging.info("***********************************************")
|
||||
logging.info("****** AMQ Service Init Complete *********")
|
||||
logging.info("***********************************************")
|
||||
self.future.set_result(True)
|
||||
self.loop.run_forever()
|
||||
|
||||
def backpressure(self, current_availability: int, maximum: int = -1):
|
||||
@@ -163,6 +165,48 @@ class AMQService:
|
||||
return True
|
||||
return False
|
||||
|
||||
async def data_message_generator(self, route: AMQRoute) -> AsyncIterator[DataMessage]:
|
||||
"""
|
||||
An async iterator that blocks until messages arrive, processes them,
|
||||
and continues in a loop.
|
||||
|
||||
:param queue_name: The name of the queue to consume messages from
|
||||
:yield: The processed DataResponse for each message
|
||||
"""
|
||||
# Get a channel from the connection
|
||||
channel = self.rabbit_mq_client.channel
|
||||
queue_args = (
|
||||
self.rabbit_mq_client.DLQ_ARGS if self.amq_configuration.dispatch.use_dlq else None
|
||||
)
|
||||
queue = await channel.declare_queue(
|
||||
route.queue,
|
||||
durable=True,
|
||||
exclusive=False,
|
||||
auto_delete=False,
|
||||
arguments=queue_args,
|
||||
)
|
||||
await queue.bind(route.exchange, route.key)
|
||||
# Start consuming without a callback
|
||||
async with queue.iterator() as queue_iter:
|
||||
async for message in queue_iter:
|
||||
try:
|
||||
# Process the message using the same logic as in inbound_data_message_callback_no_thread
|
||||
data_message: DataMessage = (
|
||||
await self.amq_data_message_handler.reconstitute_data_message(message)
|
||||
)
|
||||
|
||||
success = yield data_message
|
||||
if not success:
|
||||
logging_warning(f"Message processing failed for {data_message.id()}.")
|
||||
# Nack the message without requeuing in case of failure
|
||||
await message.nack(requeue=False)
|
||||
else:
|
||||
await message.ack()
|
||||
except Exception as e:
|
||||
logging_error(f"Error processing message: {e}")
|
||||
# Nack the message without requeuing in case of error
|
||||
await message.nack(requeue=False)
|
||||
|
||||
def get_unique_instance_id(self) -> int:
|
||||
"""
|
||||
Provides cluster-wide unique instance ID for this AMQ service instance.
|
||||
|
||||
Reference in New Issue
Block a user