Cria novos components
This commit is contained in:
85
video_render/messaging.py
Normal file
85
video_render/messaging.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, Callable, Dict
|
||||
|
||||
import pika
|
||||
|
||||
from .config import Settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MessageHandler = Callable[[Dict[str, Any]], Dict[str, Any]]
|
||||
|
||||
|
||||
class RabbitMQWorker:
|
||||
def __init__(self, settings: Settings) -> None:
|
||||
self.settings = settings
|
||||
self._params = pika.ConnectionParameters(
|
||||
host=settings.rabbitmq.host,
|
||||
port=settings.rabbitmq.port,
|
||||
credentials=pika.PlainCredentials(
|
||||
settings.rabbitmq.user, settings.rabbitmq.password
|
||||
),
|
||||
heartbeat=settings.rabbitmq.heartbeat,
|
||||
blocked_connection_timeout=settings.rabbitmq.blocked_timeout,
|
||||
)
|
||||
|
||||
def consume_forever(self, handler: MessageHandler) -> None:
|
||||
while True:
|
||||
try:
|
||||
with pika.BlockingConnection(self._params) as connection:
|
||||
channel = connection.channel()
|
||||
channel.queue_declare(queue=self.settings.rabbitmq.consume_queue, durable=True)
|
||||
channel.queue_declare(queue=self.settings.rabbitmq.publish_queue, durable=True)
|
||||
channel.basic_qos(prefetch_count=self.settings.rabbitmq.prefetch_count)
|
||||
|
||||
def _on_message(ch: pika.adapters.blocking_connection.BlockingChannel, method, properties, body):
|
||||
try:
|
||||
message = json.loads(body)
|
||||
except json.JSONDecodeError:
|
||||
logger.error("Mensagem inválida recebida: %s", body)
|
||||
ch.basic_ack(delivery_tag=method.delivery_tag)
|
||||
return
|
||||
|
||||
logger.info("Mensagem recebida: %s", message.get("filename", "<sem_nome>"))
|
||||
try:
|
||||
response = handler(message)
|
||||
except Exception:
|
||||
logger.exception("Erro não tratado durante o processamento")
|
||||
response = {
|
||||
"hasError": True,
|
||||
"error": "Erro não tratado no pipeline",
|
||||
"filename": message.get("filename"),
|
||||
"videoId": message.get("videoId"),
|
||||
"url": message.get("url"),
|
||||
"processedFiles": [],
|
||||
}
|
||||
|
||||
try:
|
||||
payload = json.dumps(response)
|
||||
ch.basic_publish(
|
||||
exchange="",
|
||||
routing_key=self.settings.rabbitmq.publish_queue,
|
||||
body=payload,
|
||||
properties=pika.BasicProperties(delivery_mode=2),
|
||||
)
|
||||
logger.info("Resposta publicada para '%s'", self.settings.rabbitmq.publish_queue)
|
||||
except Exception:
|
||||
logger.exception("Falha ao publicar a resposta na fila de upload")
|
||||
finally:
|
||||
ch.basic_ack(delivery_tag=method.delivery_tag)
|
||||
|
||||
channel.basic_consume(
|
||||
queue=self.settings.rabbitmq.consume_queue,
|
||||
on_message_callback=_on_message,
|
||||
auto_ack=False,
|
||||
)
|
||||
logger.info("Consumidor iniciado. Aguardando mensagens...")
|
||||
channel.start_consuming()
|
||||
except pika.exceptions.AMQPConnectionError:
|
||||
logger.exception("Conexão com RabbitMQ perdida. Tentando reconectar...")
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Encerrando consumidor por interrupção do usuário.")
|
||||
break
|
||||
Reference in New Issue
Block a user