From 975d3f5fee104ff12bd0fd0fbebf82c7d9ef2e99 Mon Sep 17 00:00:00 2001 From: jar3b Date: Wed, 5 Dec 2018 19:23:39 +0300 Subject: [PATCH] Update code and readme --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ queued_mailer/backend.py | 8 ++------ queued_mailer/settings.py | 6 +++--- queued_mailer/tasks.py | 24 ++++++++++++++++-------- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5d0c0b8..c3cb4c8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,41 @@ # django-queued-mailer + Django mail backend uses celery as email message queue + +### requirements + +Django >= 1.11, Celery >= 4.1.1 + +### setup + +- add `git+https://github.com/jar3b/django-queued-mailer.git` to requirements.txt +- install package `pip install --upgrade git+https://github.com/jar3b/django-queued-mailer.git` +- run celery worker + +``` +celery -A project worker +``` + +### run one task at time (optional) + +- setup Celery routes + +``` +app.conf.task_queues = ( + Queue('default', Exchange('default'), routing_key='default'), + Queue('qmailer_mail_queue', routing_key='qmailer.send.#'), +) +``` + +- start separate worker + +``` +celery -A project worker -Q qmailer_mail_queue --concurrency=1 +``` + +### configure + +Django settings: + +- `QMAILER_EMAIL_BACKEND` - set email backend, default `django.core.mail.backends.smtp.EmailBackend` +- `QMAILER_TASK_QUEUE_NAME` - queue name for routing, default `default`, if you use separate "serial" worker as described above, you need to specify this option \ No newline at end of file diff --git a/queued_mailer/backend.py b/queued_mailer/backend.py index 39ee2c3..4740d32 100644 --- a/queued_mailer/backend.py +++ b/queued_mailer/backend.py @@ -1,9 +1,8 @@ from django.core.mail.backends.base import BaseEmailBackend from django.utils.encoding import force_text -from django.utils.module_loading import import_string from .logger import logger -from .settings import EMAIL_SEND_TASK +from .tasks import send_message def _get_message_recipients(email_message): @@ -14,17 +13,14 @@ def _get_message_recipients(email_message): class EmailBackend(BaseEmailBackend): - task = None - def __init__(self, fail_silently=False, **kwargs): super(EmailBackend, self).__init__(fail_silently, **kwargs) - self.task = import_string(EMAIL_SEND_TASK) def send_messages(self, email_messages): num_sent = 0 for email in email_messages: try: - self.task.apply_async([email, ]) + send_message.apply_async([email, ]) num_sent += 1 except Exception as e: logger.error("cannot send message %s: %r" % (_get_message_recipients(email), e)) diff --git a/queued_mailer/settings.py b/queued_mailer/settings.py index e802a62..3ce6476 100644 --- a/queued_mailer/settings.py +++ b/queued_mailer/settings.py @@ -6,8 +6,8 @@ EMAIL_BACKEND = getattr( "django.core.mail.backends.smtp.EmailBackend" ) -EMAIL_SEND_TASK = getattr( +TASK_QUEUE_NAME = getattr( settings, - "QMAILER_SEND_TASK", - "queued_mailer.tasks.send_message" + "QMAILER_TASK_QUEUE_NAME", + "default" ) diff --git a/queued_mailer/tasks.py b/queued_mailer/tasks.py index b03764b..ddb8cdc 100644 --- a/queued_mailer/tasks.py +++ b/queued_mailer/tasks.py @@ -1,11 +1,19 @@ -from celery.task import task +from time import sleep -from .logger import logger -from .settings import EMAIL_BACKEND +import celery +from celery.utils.log import get_task_logger + +from .settings import TASK_QUEUE_NAME + +logger = get_task_logger(__name__) -@task -def send_message(email): - logger.info('TASK CALLED') - logger.info(EMAIL_BACKEND) - logger.info(email) +@celery.task(bind=True, queue=TASK_QUEUE_NAME, acks_late=True, default_retry_delay=30) +def send_message(self, email): + logger.info('task started') + try: + sleep(5) + logger.info('task success') + except Exception as e: + logger.info('task error') + raise self.retry(exc=e)