85 lines
3.9 KiB
Python
85 lines
3.9 KiB
Python
import queue
|
|
import threading
|
|
import time
|
|
import logging
|
|
from managers.telegram_manager_factory import TelegramManagerFactory
|
|
|
|
MESSAGE_DELAY = 3.0 # Tiempo de espera entre mensajes en segundos
|
|
RETRY_TIMES = 3
|
|
|
|
class QueueManager:
|
|
def __init__(self, article_cache, mongodb_config=None):
|
|
self.logger = logging.getLogger(__name__)
|
|
self._queue = queue.Queue() # Cola thread-safe: (username, search_name, article, thread_id, retry_times)
|
|
self._article_cache = article_cache
|
|
self._running = True
|
|
|
|
# Inicializar factory de TelegramManager
|
|
TelegramManagerFactory.initialize(mongodb_config)
|
|
|
|
# Iniciar el thread de procesamiento
|
|
self._processor_thread = threading.Thread(target=self._process_queue, daemon=True)
|
|
self._processor_thread.start()
|
|
|
|
def add_to_queue(self, article, search_name=None, thread_id=None, retry_times=RETRY_TIMES, username=None):
|
|
# Verificar si el artículo ya ha sido enviado
|
|
if self._article_cache.is_article_notified(article):
|
|
return
|
|
|
|
if search_name is None:
|
|
search_name = "Unknown"
|
|
# Añadir username a la cola para usar el bot correcto
|
|
self._queue.put((username, search_name, article, thread_id, retry_times))
|
|
self.logger.debug(f"Artículo añadido a la cola para usuario '{username}': {article.get_title()}")
|
|
|
|
self._article_cache.mark_article_as_notified(article, username=username, worker_name=search_name)
|
|
|
|
def add_to_notified_articles(self, articles, username=None, worker_name=None):
|
|
"""Añade artículos a la lista de artículos ya notificados"""
|
|
self._article_cache.mark_articles_as_notified(articles, username=username, worker_name=worker_name)
|
|
|
|
def _process_queue(self):
|
|
self.logger.info("Procesador de cola: Iniciado")
|
|
|
|
while self._running:
|
|
try:
|
|
# Esperar hasta que haya un elemento en la cola (timeout de 1 segundo)
|
|
try:
|
|
username, search_name, article, thread_id, retry_times = self._queue.get(timeout=1.0)
|
|
except queue.Empty:
|
|
continue
|
|
|
|
# Obtener TelegramManager para el usuario específico
|
|
telegram_manager = TelegramManagerFactory.get_manager(username)
|
|
|
|
if telegram_manager is None:
|
|
self.logger.warning(f"No hay TelegramManager disponible para usuario '{username}', saltando artículo")
|
|
self._queue.task_done()
|
|
continue
|
|
|
|
# Procesar el artículo
|
|
try:
|
|
telegram_manager.send_telegram_article(search_name, article, thread_id)
|
|
except Exception as e:
|
|
self.logger.error(f"Error al enviar artículo a Telegram para usuario '{username}': {e}")
|
|
if retry_times > 0:
|
|
self._queue.put((username, search_name, article, thread_id, retry_times - 1))
|
|
else:
|
|
self.logger.error(f"Artículo no enviado después de {RETRY_TIMES} intentos para usuario '{username}'")
|
|
finally:
|
|
self._queue.task_done()
|
|
|
|
# Esperar antes de procesar el siguiente mensaje
|
|
if not self._queue.empty():
|
|
self.logger.debug(f"Esperando {MESSAGE_DELAY}s antes del próximo mensaje")
|
|
time.sleep(MESSAGE_DELAY)
|
|
|
|
except Exception as e:
|
|
self.logger.error(f"Error en el procesador de cola: {e}")
|
|
time.sleep(1.0)
|
|
|
|
def stop(self):
|
|
"""Detiene el procesador de cola"""
|
|
self.logger.info("Deteniendo procesador de cola...")
|
|
self._running = False
|
|
self._processor_thread.join(timeout=5.0) |