Ctrl K
ComunidadGuías…

backend/worker.py

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""RQ worker entry point for Sublarr background jobs.

Start this process alongside the main Flask app to enable persistent,
Redis-backed job queuing. Each job runs inside a Flask application context
so that db.session, config, and all Flask extensions are available.

Usage:
    python worker.py

Configuration via environment variables (same as the main app):
    SUBLARR_REDIS_URL   Redis connection URL (required)
    SUBLARR_QUEUE_NAME  Queue name (default: sublarr)

Docker:
    Use docker-compose.redis.yml which configures the rq-worker service.
    Scale workers with:
        docker compose -f docker-compose.redis.yml up -d --scale rq-worker=N
"""

import logging
import os
import sys

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s %(message)s",
)
logger = logging.getLogger(__name__)


class _AppContextWorker:
    """Mixin that pushes a Flask app context around every RQ job.

    Defined at module level so it is picklable (required by RQ).
    """

    _app = None

    @classmethod
    def set_app(cls, app):
        cls._app = app

    def perform_job(self, job, queue, *args, **kwargs):
        if self._app is not None:
            with self._app.app_context():
                return super().perform_job(job, queue, *args, **kwargs)
        return super().perform_job(job, queue, *args, **kwargs)


def main():
    from app import create_app

    try:
        from redis import Redis
        from rq import Queue, Worker
    except ImportError as exc:
        logger.error("redis and rq packages are required: %s", exc)
        sys.exit(1)

    redis_url = os.environ.get("SUBLARR_REDIS_URL", "")
    if not redis_url:
        # Fall back to Pydantic settings so the same env var works
        try:
            from config import get_settings

            redis_url = get_settings().redis_url
        except Exception:
            logger.debug("Could not read the Redis URL from the settings", exc_info=True)

    if not redis_url:
        logger.error(
            "SUBLARR_REDIS_URL is not set. Set it to a Redis connection URL, "
            "e.g. redis://localhost:6379/0"
        )
        sys.exit(1)

    queue_name = os.environ.get("SUBLARR_QUEUE_NAME", "sublarr")

    app = create_app()

    try:
        redis_conn = Redis.from_url(redis_url, socket_connect_timeout=10)
        redis_conn.ping()
    except Exception as exc:
        logger.error("Cannot connect to Redis at %s: %s", redis_url, exc)
        sys.exit(1)

    # Build a Worker subclass with app context support
    class AppContextWorker(_AppContextWorker, Worker):
        pass

    AppContextWorker.set_app(app)

    queues = [Queue(queue_name, connection=redis_conn)]
    worker = AppContextWorker(queues, connection=redis_conn)

    logger.info("Sublarr RQ worker started — queue=%s  redis=%s", queue_name, redis_url)
    worker.work(with_scheduler=False)


if __name__ == "__main__":
    main()