From b44096b07c3d1189730eb9bb78e2a44f51ed0790 Mon Sep 17 00:00:00 2001 From: jlimolina Date: Mon, 4 Aug 2025 21:10:33 +0000 Subject: [PATCH] =?UTF-8?q?Actualizaci=C3=B3n=20del=202025-08-04=20a=20las?= =?UTF-8?q?=2021:10:33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 2 +- scheduler.py | 24 +++++++++++++++--------- worker.py | 29 ++++++++++++----------------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/app.py b/app.py index 48da149..a0c51d7 100644 --- a/app.py +++ b/app.py @@ -643,4 +643,4 @@ if __name__ == "__main__": if not db_pool: app.logger.error("La aplicación no puede arrancar sin una conexión a la base de datos.") sys.exit(1) - app.run(host="0.0.0.0", port=8000, debug=True) + app.run(host="0.0.0.0", port=8001, debug=True) diff --git a/scheduler.py b/scheduler.py index 5af27f4..bcbb1c1 100644 --- a/scheduler.py +++ b/scheduler.py @@ -4,11 +4,12 @@ import time import logging import atexit from datetime import datetime, timedelta -import sys # Added this import +import sys from apscheduler.schedulers.background import BackgroundScheduler # Importamos la app (para el contexto) y la función de captura desde nuestro fichero principal -from app import app, fetch_and_store +# --- CORRECCIÓN 1: Se cambió 'fetch_and_store' por 'fetch_and_store_all' --- +from app import app, fetch_and_store_all # Es importante configurar el logging también para este proceso logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='[%(asctime)s] %(levelname)s in %(module)s: %(message)s') @@ -16,7 +17,7 @@ logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='[%(asctime)s] # Creamos el planificador con la zona horaria UTC para evitar ambigüedades scheduler = BackgroundScheduler(daemon=True, timezone="UTC") -# --- INICIO DE LA MEJORA: Apagado robusto con atexit --- +# --- Apagado robusto con atexit --- def shutdown_scheduler(): """Función para detener el planificador de forma segura al salir.""" if scheduler.running: @@ -25,15 +26,15 @@ def shutdown_scheduler(): # Registramos la función de apagado para que se ejecute al terminar el proceso atexit.register(shutdown_scheduler) -# --- FIN DE LA MEJORA --- if __name__ == '__main__': # Usamos el contexto de la aplicación para asegurar que la tarea tiene acceso a todo lo necesario with app.app_context(): - # Añadimos la tarea para que se ejecute cada 15 minutos + # Añadimos la tarea para que se ejecute cada 3 minutos # La primera ejecución será a los 10 segundos de arrancar el worker scheduler.add_job( - fetch_and_store, + # --- CORRECCIÓN 2: Se cambió 'fetch_and_store' por 'fetch_and_store_all' --- + fetch_and_store_all, "interval", minutes=3, id="rss_job", @@ -43,10 +44,15 @@ if __name__ == '__main__': # Arrancamos el planificador scheduler.start() - logging.info("Worker del Scheduler iniciado. Tarea programada cada 15 minutos.") + logging.info("Worker del Scheduler iniciado. Tarea programada cada 3 minutos.") logging.info("El proceso se mantendrá en ejecución para permitir que se ejecuten las tareas.") # Este bucle infinito simplemente mantiene vivo el script del worker. # El apagado ahora es manejado por atexit. - while True: - time.sleep(60) + try: + while True: + time.sleep(60) + except (KeyboardInterrupt, SystemExit): + logging.info("Apagando el worker...") + + diff --git a/worker.py b/worker.py index 689c4dc..4e183c2 100644 --- a/worker.py +++ b/worker.py @@ -1,18 +1,13 @@ import sys -import logging # <--- ¡LA LÍNEA QUE FALTABA! -from app import fetch_and_store_all, app - -# Añadimos un logger para ver la salida en el journal de systemd -handler = logging.StreamHandler(sys.stdout) -handler.setLevel(logging.INFO) -handler.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s in %(module)s: %(message)s')) -app.logger.addHandler(handler) - -if __name__ == '__main__': - app.logger.info("Iniciando tarea de recolección desde worker.py...") - try: - # Llamamos a la función con el nombre correcto - fetch_and_store_all() - app.logger.info("Tarea de recolección finalizada exitosamente.") - except Exception as e: - app.logger.error(f"La tarea de recolección falló con una excepción: {e}", exc_info=True) +import os +import logging +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +try: + from app import app, fetch_and_store +except ImportError as e: + logging.basicConfig() + logging.critical(f"No se pudo importar la aplicación Flask. Error: {e}") + sys.exit(1) +if __name__ == "__main__": + with app.app_context(): + fetch_and_store()