From 66724c40f9e5e0350e1fedfcfc282c75d438a598 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 23 Dec 2024 19:40:41 +0100 Subject: [PATCH] celery --- .env.example | 2 ++ docs/explanation/technos.md | 25 +++++++++++++++++++++++++ docs/tutorial/install-advanced.md | 14 ++++++++++++++ sith/__init__.py | 6 ++++++ sith/celery.py | 18 ++++++++++++++++++ sith/settings.py | 17 +++++++++++++++++ 6 files changed, 82 insertions(+) create mode 100644 sith/celery.py diff --git a/.env.example b/.env.example index 266af2a19..bab595ffa 100644 --- a/.env.example +++ b/.env.example @@ -9,6 +9,8 @@ DATABASE_URL=sqlite:///db.sqlite3 #DATABASE_URL=postgres://user:password@127.0.0.1:5432/sith CACHE_URL=redis://127.0.0.1:6379/0 +CELERY_BROKER_URL=redis://127.0.0.1:6379/1 + MEDIA_ROOT=data STATIC_ROOT=static diff --git a/docs/explanation/technos.md b/docs/explanation/technos.md index 88e15aa5f..542bd95d7 100644 --- a/docs/explanation/technos.md +++ b/docs/explanation/technos.md @@ -131,6 +131,31 @@ de données fonctionnent avec l'un comme avec l'autre. Heureusement, et grâce à l'ORM de Django, cette double compatibilité est presque toujours possible. +### Celery + +[Site officiel](https://docs.celeryq.dev/en/stable/) + +Dans certaines situations, on veut séparer une tâche +pour la faire tourner dans son coin. +Deux cas qui correspondent à cette situation sont : + +- les tâches longues à exécuter + (comme l'envoi de mail ou la génération de documents), + pour lesquelles on veut pouvoir dire à l'utilisateur + que sa requête a été prise en compte, sans pour autant + le faire trop patienter +- les tâches régulières séparées du cycle requête/réponse. + +Pour ça, nous utilisons Celery. +Grâce à son intégration avec Django, +il permet de mettre en place une queue de message +avec assez peu complexité ajoutée. + +En outre, ses extensions `django-celery-results` +et `django-celery-beat` enrichissent son intégration +avec django et offrent des moyens de manipuler certaines +tâches directement dans l'interface admin de django. + ## Frontend ### Jinja2 diff --git a/docs/tutorial/install-advanced.md b/docs/tutorial/install-advanced.md index 357d013c0..e2d3aa5e0 100644 --- a/docs/tutorial/install-advanced.md +++ b/docs/tutorial/install-advanced.md @@ -227,6 +227,20 @@ Toutes les requêtes vers des fichiers statiques et les medias publiques seront seront servies directement par nginx. Toutes les autres requêtes seront transmises au serveur django. +## Celery + +Celery ne tourne pas dans django. +C'est une application à part, avec ses propres processus, +qui tourne de manière indépendante et qui ne communique +que par messages avec l'instance de django. + +Pour faire tourner Celery, faites la commande suivante dans +un terminal à part : + +```bash +poetry run celery -A sith worker --beat -l INFO +``` + ## Mettre à jour la base de données antispam diff --git a/sith/__init__.py b/sith/__init__.py index f4445e699..1c1f4f81d 100644 --- a/sith/__init__.py +++ b/sith/__init__.py @@ -12,3 +12,9 @@ # OR WITHIN THE LOCAL FILE "LICENSE" # # + +# This will make sure the app is always imported when +# Django starts so that shared_task will use this app. +from .celery import app as celery_app + +__all__ = ("celery_app",) diff --git a/sith/celery.py b/sith/celery.py new file mode 100644 index 000000000..55d03cb94 --- /dev/null +++ b/sith/celery.py @@ -0,0 +1,18 @@ +# Set the default Django settings module for the 'celery' program. +import os + +from celery import Celery + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sith.settings") + +app = Celery("sith") + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object("django.conf:settings", namespace="CELERY") + +# Load task modules from all registered Django apps. +app.autodiscover_tasks() + diff --git a/sith/settings.py b/sith/settings.py index 598e1fb6b..adeb3eb2c 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -88,6 +88,8 @@ "django_jinja", "ninja_extra", "haystack", + "django_celery_results", + "django_celery_beat", "captcha", "core", "club", @@ -285,6 +287,13 @@ "django.contrib.staticfiles.finders.AppDirectoriesFinder", ] +CACHES = { + "default": { + "BACKEND": "django.core.cache.backends.redis.RedisCache", + "LOCATION": "redis://127.0.0.1:6379", + } +} + STORAGES = { "default": { "BACKEND": "django.core.files.storage.FileSystemStorage", @@ -319,6 +328,14 @@ EMAIL_HOST = env.str("EMAIL_HOST", default="localhost") EMAIL_PORT = env.int("EMAIL_PORT", default=25) +# Celery +CELERY_TIMEZONE = TIME_ZONE +CELERY_TASK_TRACK_STARTED = True +CELERY_TASK_TIME_LIMIT = 30 * 60 +CElERY_BROKER_URL = env.str("CELERY_BROKER_URL", default="redis://localhost:6379/1") +CELERY_RESULT_BACKEND = "django-db" +CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" + # Below this line, only Sith-specific variables are defined SITH_URL = env.str("SITH_URL", default="127.0.0.1:8000")