Only use RQ 2.4+ and its cron capabilities.

This commit is contained in:
Antoine Nguyen
2026-01-06 15:30:53 +01:00
parent 4d60258298
commit c147eb80e4
7 changed files with 68 additions and 84 deletions
+16 -1
View File
@@ -38,7 +38,22 @@ services:
PYTHONPATH: ".."
PYTHONUNBUFFERED: 1
command: >
sh -c "cd test_project; python3 manage.py rqworker dkim modoboa"
sh -c "cd test_project; python3 manage.py rqworker dkim modoboa dovecot"
volumes:
- .:/code
rq-scheduler:
build:
context: .
dockerfile: docker/Dockerfile.dev
environment:
DB: "SQLITE"
DEBUG: 1
REDIS_HOST: redis
PYTHONPATH: ".."
PYTHONUNBUFFERED: 1
command: >
sh -c "cd test_project; python3 manage.py rqcron test_project/cron_config.py"
volumes:
- .:/code
+17 -59
View File
@@ -1,26 +1,19 @@
"""Script to register RQ jobs."""
"""Async jobs definition."""
import logging
import os
import shutil
from modoboa.admin.app_settings import load_admin_settings
from modoboa.admin.models.mailbox import MailboxOperation
from modoboa.lib.sysutils import exec_cmd
from modoboa.parameters import tools as param_tools
logger = logging.getLogger("modoboa.jobs")
def rename_mailbox(op_id):
def rename_mailbox(operation):
"""Rename the mailbox folder through a RQ Job."""
import logging
import os
from modoboa.admin.app_settings import load_admin_settings
from modoboa.admin.models.mailbox import MailboxOperation
from modoboa.lib.sysutils import exec_cmd
from modoboa.parameters import tools as param_tools
logger = logging.getLogger("modoboa.admin")
load_admin_settings()
if not param_tools.get_global_parameter("handle_mailboxes"):
return
try:
operation = MailboxOperation.objects.get(pk=op_id)
except MailboxOperation.DoesNotExist:
logger.error(f"Failed to retrieve operation id {op_id} for renaming")
return
if not os.path.exists(operation.argument):
logger.error(f"Failed to rename {operation.argument}, folder not found")
operation.delete()
@@ -43,38 +36,15 @@ def rename_mailbox(op_id):
operation.delete()
def delete_mailbox(op_id):
def delete_mailbox(operation):
"""Delete the mailbox folder through a RQ Job."""
import logging
import os
import shutil
from modoboa.admin.app_settings import load_admin_settings
from modoboa.admin.models.mailbox import MailboxOperation
from modoboa.parameters import tools as param_tools
logger = logging.getLogger("modoboa.admin")
load_admin_settings()
if not param_tools.get_global_parameter("handle_mailboxes"):
return
try:
operation = MailboxOperation.objects.get(pk=op_id)
except MailboxOperation.DoesNotExist:
logger.error(f"Failed to retrieve operation id {op_id} for deletion")
return
if not os.path.exists(operation.argument):
logger.error(f"Failed to delete {operation.argument}, folder not found")
operation.delete()
return
def onerror(function, path, excinfo):
import logging
"""Handle errors."""
logger = logging.getLogger("modoboa.admin")
logger.critical(f"delete failed (reason: {excinfo})")
operation.delete()
@@ -82,24 +52,12 @@ def delete_mailbox(op_id):
operation.delete()
def handle_remaining_operation():
import logging
import django_rq
from modoboa.parameters import tools as param_tools
from modoboa.admin.app_settings import load_admin_settings
from modoboa.admin.models.mailbox import MailboxOperation
def handle_mailbox_operations():
load_admin_settings()
if not param_tools.get_global_parameter("handle_mailboxes"):
return
queue = django_rq.get_queue("dovecot")
if queue.started_job_registry.count > 0 or queue.scheduled_job_registry.count > 0:
return
logger = logging.getLogger("modoboa.admin")
for ope in MailboxOperation.objects.all():
if ope.type == "rename":
rename_mailbox(ope.pk)
rename_mailbox(ope)
elif ope.type == "delete":
delete_mailbox(ope.pk)
delete_mailbox(ope)
+2 -13
View File
@@ -9,15 +9,12 @@ from django.db.models.manager import Manager
from django.utils.encoding import smart_str, force_str
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.admin import jobs
from modoboa.core.models import User
from modoboa.lib import exceptions as lib_exceptions
from modoboa.lib.email_utils import split_mailbox
from modoboa.lib.sysutils import doveadm_cmd
from modoboa.parameters import tools as param_tools
import django_rq
from .base import AdminObject
from .domain import Domain
from . import mixins
@@ -195,12 +192,9 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject):
hm = param_tools.get_global_parameter("handle_mailboxes", raise_exception=False)
if not hm:
return
mail_op = MailboxOperation.objects.create(
MailboxOperation.objects.create(
mailbox=self, type="rename", argument=old_mail_home
)
mail_op.save()
dovecot_queue = django_rq.get_queue("dovecot")
dovecot_queue.enqueue(jobs.rename_mailbox, mail_op.pk)
def rename(self, address, domain):
"""Rename the mailbox.
@@ -229,12 +223,7 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject):
hm = param_tools.get_global_parameter("handle_mailboxes", raise_exception=False)
if not hm:
return
mail_op = MailboxOperation.objects.create(
type="delete", argument=self.mail_home
)
mail_op.save()
dovecot_queue = django_rq.get_queue("dovecot")
dovecot_queue.enqueue(jobs.delete_mailbox, mail_op.pk)
MailboxOperation.objects.create(type="delete", argument=self.mail_home)
def set_quota(self, value=None, override_rules=False):
"""Set or update quota value for this mailbox.
+23 -9
View File
@@ -1,14 +1,28 @@
"""Core Jobs"""
"""Async jobs definition."""
import datetime
import logging
from modoboa.core.models import Log
from modoboa.maillog.models import Maillog
from modoboa.parameters import tools as param_tools
from django.utils import timezone
logger = logging.getLogger("modoboa.jobs")
def clean_log():
import datetime
from modoboa.core.models import Log
from modoboa.parameters import tools as param_tools
from django.utils import timezone
def clean_logs():
log_maximum_age = param_tools.get_global_parameter("log_maximum_age")
logger.info(f"Deleting logs older than {log_maximum_age} days...")
limit = timezone.now() - datetime.timedelta(log_maximum_age)
Log.objects.filter(date_created__lt=limit).delete()
message_history_maximum_age = param_tools.get_global_parameter(
"message_history_maximum_age"
)
logger.info(
f"Deleting messages in history older than {message_history_maximum_age} days..."
)
limit = timezone.now() - datetime.timedelta(message_history_maximum_age)
Maillog.objects.filter(date__lt=limit).delete()
+1 -2
View File
@@ -70,9 +70,8 @@ dependencies = [
"defusedxml>=0.6.0",
"python-magic>=0.4.24",
# RQ
"rq>=1.13.0",
"rq>=2.4.0",
"django-rq",
"rq-scheduler",
# Sieve
"sievelib>=1.4.1",
# User
+8
View File
@@ -0,0 +1,8 @@
from rq.cron import register
from modoboa.core import jobs as core_jobs
from modoboa.admin import jobs as admin_jobs
register(admin_jobs.handle_mailbox_operations, queue_name="dovecot", cron="* * * * *")
register(core_jobs.clean_logs, queue_name="modoboa", cron="0 0 * * *")
+1
View File
@@ -385,6 +385,7 @@ LOGGING = {
},
"modoboa.admin": {"handlers": ["modoboa"], "level": "INFO", "propagate": False},
"modoboa.dns": {"handlers": ["syslog"], "level": "INFO", "propagate": False},
"modoboa.jobs": {"handlers": ["syslog"], "level": "INFO", "propagate": False},
"django.server": {
"handlers": ["django.server"],
"level": "INFO",