75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
|
|
"""
|
||
|
|
Registriert den Retention-Cleanup als Periodic Task in django_celery_beat.
|
||
|
|
|
||
|
|
Standardplan: täglich um 03:15 Uhr (kollidiert nicht mit dem Backup-Service,
|
||
|
|
der i.d.R. um 03:00 läuft, und liegt in der Wartungsphase).
|
||
|
|
|
||
|
|
Die Zeitzone richtet sich nach `settings.CELERY_TIMEZONE` bzw. `TIME_ZONE`.
|
||
|
|
"""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from django.db import migrations
|
||
|
|
|
||
|
|
|
||
|
|
CRON_HOUR = "3"
|
||
|
|
CRON_MINUTE = "15"
|
||
|
|
TASK_NAME = "Retention-Cleanup: abgelaufene Jobs löschen"
|
||
|
|
TASK_DOTTED = "mailmerge.cleanup_expired_jobs"
|
||
|
|
|
||
|
|
|
||
|
|
def create_periodic_task(apps, schema_editor):
|
||
|
|
CrontabSchedule = apps.get_model("django_celery_beat", "CrontabSchedule")
|
||
|
|
PeriodicTask = apps.get_model("django_celery_beat", "PeriodicTask")
|
||
|
|
|
||
|
|
from django.conf import settings
|
||
|
|
|
||
|
|
schedule, _ = CrontabSchedule.objects.get_or_create(
|
||
|
|
minute=CRON_MINUTE,
|
||
|
|
hour=CRON_HOUR,
|
||
|
|
day_of_week="*",
|
||
|
|
day_of_month="*",
|
||
|
|
month_of_year="*",
|
||
|
|
timezone=getattr(settings, "CELERY_TIMEZONE", settings.TIME_ZONE),
|
||
|
|
)
|
||
|
|
|
||
|
|
PeriodicTask.objects.update_or_create(
|
||
|
|
name=TASK_NAME,
|
||
|
|
defaults={
|
||
|
|
"crontab": schedule,
|
||
|
|
"task": TASK_DOTTED,
|
||
|
|
"enabled": True,
|
||
|
|
"description": (
|
||
|
|
"Entfernt MailMergeJobs im Status DONE/FAILED, deren "
|
||
|
|
"finished_at älter als JOB_RETENTION_DAYS ist. "
|
||
|
|
"Inkl. recipients_csv und result_pdf auf dem Storage."
|
||
|
|
),
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def remove_periodic_task(apps, schema_editor):
|
||
|
|
PeriodicTask = apps.get_model("django_celery_beat", "PeriodicTask")
|
||
|
|
PeriodicTask.objects.filter(name=TASK_NAME).delete()
|
||
|
|
|
||
|
|
|
||
|
|
class Migration(migrations.Migration):
|
||
|
|
"""Achtung: Wir definieren KEINE konkrete Migrationsabhängigkeit zu
|
||
|
|
django_celery_beat, weil dessen letzte Migration je Paketversion
|
||
|
|
unterschiedlich heißt. `run_before`/`dependencies` mit `("__latest__")`
|
||
|
|
gibt es nicht. Stattdessen verlassen wir uns auf die Reihenfolge:
|
||
|
|
django_celery_beat steht in INSTALLED_APPS und wird mit `migrate` immer
|
||
|
|
vorab gewandert (Django sortiert nach Abhängigkeiten der App-Initials).
|
||
|
|
|
||
|
|
Beim Build wird `migrate` ohnehin sequentiell ausgeführt, daher läuft
|
||
|
|
diese Migration zuverlässig nach allen django_celery_beat-Migrationen,
|
||
|
|
sobald `mailmerge.0001_initial` durch ist.
|
||
|
|
"""
|
||
|
|
|
||
|
|
dependencies = [
|
||
|
|
("mailmerge", "0001_initial"),
|
||
|
|
]
|
||
|
|
|
||
|
|
operations = [
|
||
|
|
migrations.RunPython(create_periodic_task, remove_periodic_task),
|
||
|
|
]
|