Koed00 / django-q

A multiprocessing distributed task queue for Django
https://django-q.readthedocs.org
MIT License
1.83k stars 285 forks source link

Django-Q with db-router and redis as broker #652

Open RajeevKL-DreamLane opened 2 years ago

RajeevKL-DreamLane commented 2 years ago

I am trying to setup django-q on a separate db as my default db has high load and using redis as a broker. doing this throws an error

10:46:02 [Q] ERROR select_for_update cannot be used outside of a transaction.

this is my current settings:

DATABASE_ROUTERS = ["dashboard.router.DjangoQRouter"]

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": os.environ.get("DEFAULT_DB_NAME"),
        "USER": os.environ.get("DEFAULT_DB_USER"),
        "PASSWORD": os.environ.get("DEFAULT_DB_PASSWORD"),
        "HOST": os.environ.get("DEFAULT_DB_HOST"),
        "PORT": os.environ.get("DEFAULT_DB_PORT"),
    },
    "django_q_db": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": os.environ.get("DJANGOQ_DB_NAME"),
        "USER": os.environ.get("DJANGOQ_DB_USER"),
        "PASSWORD": os.environ.get("DJANGOQ_DB_PASSWORD"),
        "HOST": os.environ.get("DJANGOQ_DB_HOST"),
        "PORT": os.environ.get("DJANGOQ_DB_PORT"),
    }
}

this is my router config:

class DjangoQRouter:
    def __init__(self):
        self.route_app_labels = {'django_q'}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'django_q_db'
        return 'default'

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'django_q_db'
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.route_app_labels:
            return db == 'django_q_db'
        return db == 'default'

this is my django-q config:

REDIS_HOST = os.environ.get("REDIS_URL", "")
REDIS_PORT = os.environ.get("REDIS_PORT")
REDIS_DB = os.environ.get("REDIS_DB")
REDIS_USER = os.environ.get("REDIS_USER")
REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD")

REDIS = {
    "host": REDIS_HOST,
    "port": REDIS_PORT,
    "db": REDIS_DB,
    "username": REDIS_USER,
    "password": REDIS_PASSWORD,
}

Q_CLUSTER = {
    "name": "dashboard",
    "workers": 4,
    # 'recycle': 500,
    "timeout": 60,
    "retry": 100,
    # 'compress': True,
    # 'save_limit': 250,
    # 'queue_limit': 500,
    # 'cpu_affinity': 1,
    "label": "Django Q",
    "redis": REDIS,
}