将 celery 与 Django 一起使用时,用户未收到电子邮件
Emails are not getting received by the user while using celery with Django
我正在使用 Django1.8.2、celery3.1.23 和 RabbitMq 作为代理。我正在使用 Amazon ses 发送电子邮件。现在,当我从 django shell 发送电子邮件时,用户会收到它,但是当我通过 celery 安排它时,它会收到。
这里是项目文件:
project/src/settings/base.py (已审查)
BROKER_URL = 'amqp://'
CELERY_RESULT_BACKEND = 'rpc://'
BROKER_POOL_LIMIT = 3
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TIMEZONE = 'Asia/Kolkata'
CELERY_ENABLE_UTC = True
CELERY_SEND_TASK_ERROR_EMAILS = True
SERVER_EMAIL = 'abc@example.com'
ADMINS = [
('abc', 'abc@example.com')
]
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
DEFAULT_FROM_EMAIL = 'abc@example.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 465
EMAIL_TIMEOUT = 10
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_HOST_USER = 'abcjdjdlasskjjdklsaj'
EMAIL_HOST_PASSWORD = 'djkashdklahsjdhasljkdhjksahdjkashdjakhdak'
project/src/settings/celery_app.py
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
from kombu import serialization
serialization.registry._decoders.pop("application/x-python-serialize")
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings.production')
app = Celery('project')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
if __name__ == '__main__':
app.start()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
project/src/app/tasks.py
@task()
def send_mail_reminder(reminder_id):
logger.info("Send Email")
try:
reminder = Reminder.objects.get(pk=reminder_id)
except Reminder.DoesNotExist:
return
body = "{0}".format(reminder.message)
try:
send_mail("Reminder App Notification",body,settings.DEFAULT_FROM_EMAIL,[reminder.email])
logger.info("Email Successfully send")
return "Email Successfully send"
except Exception as e:
logger.info("There is some problem while sending email")
print e
return e
project/src/app/models.py
def schedule_reminder(self):
"""
Schedule a celery task to send the reminder
"""
date_time = datetime.combine(self.date,self.time)
reminder_time = arrow.get(date_time).replace(tzinfo=self.time_zone.zone)
from .tasks import send_sms_reminder, send_mail_reminder
# result=''
# result = send_sms_reminder.apply_async((self.pk,),eta=reminder_time,serializer = 'json')
# else:
result = send_mail_reminder.apply_async((self.pk,),eta=reminder_time, serializer = 'json')
return result.id
def save(self, *args, **kwargs):
"""
Now we need to do is ensure Django calls our
schedule_reminder method every time an Reminder object is created or updated.
"""
# Check if we have scheduled a celery task for this reminder before
if self.task_id:
#Revoke that remnder if its time has changed
celery_app.control.revoke(self.task_id)
# save our reminder, which populates self.pk,
# which is used in schedule_reminder
# Schedule a reminder task for this reminder
self.task_id = self.schedule_reminder()
# Save our reminder again with the task_id
print "Args:%s,Kwargs:%s"%(args,kwargs)
print self.task_id
super(Reminder, self).save(*args, **kwargs)
这是芹菜日志
celery.log
[tasks]
. RemindMeLater.settings.celery_app.debug_task
. Reminder.tasks.send_email_reminder
. Reminder.tasks.send_mail_reminder
. Reminder.tasks.send_sms_reminder
[2016-08-04 23:21:15,507: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2016-08-04 23:21:15,520: INFO/MainProcess] mingle: searching for neighbors
[2016-08-04 23:21:16,532: INFO/MainProcess] mingle: all alone
[2016-08-04 23:21:16,546: WARNING/MainProcess] celery@Rohans-MacBook-Pro.local ready.
[2016-08-04 23:22:21,260: INFO/MainProcess] Received task: Reminder.tasks.send_mail_reminder[e45b972a-d937-4ed9-bd75-bab331b6ed47] eta:[2016-08-04 23:22:00+05:30]
[2016-08-04 23:22:21,582: INFO/Worker-2] Reminder.tasks.send_mail_reminder[e45b972a-d937-4ed9-bd75-bab331b6ed47]: Send Email
[2016-08-04 23:22:21,608: INFO/MainProcess] Task Reminder.tasks.send_mail_reminder[e45b972a-d937-4ed9-bd75-bab331b6ed47] succeeded in 0.0274002929982s: None
[2016-08-04 23:22:46,629: INFO/MainProcess] Received task: Reminder.tasks.send_mail_reminder[7b14ef7b-c123-42c8-90d8-2baf4122963a] eta:[2016-08-04 23:24:00+05:30]
[2016-08-04 23:24:00,895: INFO/Worker-3] Reminder.tasks.send_mail_reminder[7b14ef7b-c123-42c8-90d8-2baf4122963a]: Send Email
[2016-08-04 23:24:00,920: INFO/MainProcess] Task Reminder.tasks.send_mail_reminder[7b14ef7b-c123-42c8-90d8-2baf4122963a] succeeded in 0.0263162209994s: None
当我从 Django shell 发送电子邮件而不使用 celery 时,它正在运行。当我这样做的时候,它也在进行
mail_test.py
from datetime import datetime,time
from Reminder.models import Reminder
import arrow
t = time(23,35)
date = datetime.today().date()
a = Reminder.objects.create(message="Hello world",date=date,time=t,email="abc@gmail.com",completed=False)
from Reminder.tasks import send_mail_reminder
# b = send_mail_reminder(a.id)
# print "b:",b
date_time = datetime.combine(a.date,a.time)
reminder_time = arrow.get(date_time).replace(tzinfo=a.time_zone.zone)
c = send_mail_reminder.apply_async((a.id,),eta=reminder_time, serializer='json')
print "c:",c
然后在终端执行以下命令,在celery中添加一个任务,执行成功。
./manage.py shell < mail_test.py
当我使用 post_save 信号时,它也按预期工作。
解决了。我使用 post_save 信号调用任务并使用 task_id.
保存
@receiver(post_save, sender=Reminder)
def send_email_signal(sender,instance, created, **kwargs):
if not created:
return
self = instance
date_time = datetime.combine(self.date,self.time)
reminder_time = arrow.get(date_time).replace(tzinfo=self.time_zone.zone)
from .tasks import send_sms_reminder, send_mail_reminder
result = send_mail_reminder.apply_async((self.id,),eta=reminder_time, serializer = 'json')
if result.id:
instance.task_id = result.id
instance.save()
我正在使用 Django1.8.2、celery3.1.23 和 RabbitMq 作为代理。我正在使用 Amazon ses 发送电子邮件。现在,当我从 django shell 发送电子邮件时,用户会收到它,但是当我通过 celery 安排它时,它会收到。
这里是项目文件:
project/src/settings/base.py (已审查)
BROKER_URL = 'amqp://'
CELERY_RESULT_BACKEND = 'rpc://'
BROKER_POOL_LIMIT = 3
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TIMEZONE = 'Asia/Kolkata'
CELERY_ENABLE_UTC = True
CELERY_SEND_TASK_ERROR_EMAILS = True
SERVER_EMAIL = 'abc@example.com'
ADMINS = [
('abc', 'abc@example.com')
]
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
DEFAULT_FROM_EMAIL = 'abc@example.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 465
EMAIL_TIMEOUT = 10
EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
EMAIL_HOST_USER = 'abcjdjdlasskjjdklsaj'
EMAIL_HOST_PASSWORD = 'djkashdklahsjdhasljkdhjksahdjkashdjakhdak'
project/src/settings/celery_app.py
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
from kombu import serialization
serialization.registry._decoders.pop("application/x-python-serialize")
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings.production')
app = Celery('project')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
if __name__ == '__main__':
app.start()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
project/src/app/tasks.py
@task()
def send_mail_reminder(reminder_id):
logger.info("Send Email")
try:
reminder = Reminder.objects.get(pk=reminder_id)
except Reminder.DoesNotExist:
return
body = "{0}".format(reminder.message)
try:
send_mail("Reminder App Notification",body,settings.DEFAULT_FROM_EMAIL,[reminder.email])
logger.info("Email Successfully send")
return "Email Successfully send"
except Exception as e:
logger.info("There is some problem while sending email")
print e
return e
project/src/app/models.py
def schedule_reminder(self):
"""
Schedule a celery task to send the reminder
"""
date_time = datetime.combine(self.date,self.time)
reminder_time = arrow.get(date_time).replace(tzinfo=self.time_zone.zone)
from .tasks import send_sms_reminder, send_mail_reminder
# result=''
# result = send_sms_reminder.apply_async((self.pk,),eta=reminder_time,serializer = 'json')
# else:
result = send_mail_reminder.apply_async((self.pk,),eta=reminder_time, serializer = 'json')
return result.id
def save(self, *args, **kwargs):
"""
Now we need to do is ensure Django calls our
schedule_reminder method every time an Reminder object is created or updated.
"""
# Check if we have scheduled a celery task for this reminder before
if self.task_id:
#Revoke that remnder if its time has changed
celery_app.control.revoke(self.task_id)
# save our reminder, which populates self.pk,
# which is used in schedule_reminder
# Schedule a reminder task for this reminder
self.task_id = self.schedule_reminder()
# Save our reminder again with the task_id
print "Args:%s,Kwargs:%s"%(args,kwargs)
print self.task_id
super(Reminder, self).save(*args, **kwargs)
这是芹菜日志 celery.log
[tasks]
. RemindMeLater.settings.celery_app.debug_task
. Reminder.tasks.send_email_reminder
. Reminder.tasks.send_mail_reminder
. Reminder.tasks.send_sms_reminder
[2016-08-04 23:21:15,507: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2016-08-04 23:21:15,520: INFO/MainProcess] mingle: searching for neighbors
[2016-08-04 23:21:16,532: INFO/MainProcess] mingle: all alone
[2016-08-04 23:21:16,546: WARNING/MainProcess] celery@Rohans-MacBook-Pro.local ready.
[2016-08-04 23:22:21,260: INFO/MainProcess] Received task: Reminder.tasks.send_mail_reminder[e45b972a-d937-4ed9-bd75-bab331b6ed47] eta:[2016-08-04 23:22:00+05:30]
[2016-08-04 23:22:21,582: INFO/Worker-2] Reminder.tasks.send_mail_reminder[e45b972a-d937-4ed9-bd75-bab331b6ed47]: Send Email
[2016-08-04 23:22:21,608: INFO/MainProcess] Task Reminder.tasks.send_mail_reminder[e45b972a-d937-4ed9-bd75-bab331b6ed47] succeeded in 0.0274002929982s: None
[2016-08-04 23:22:46,629: INFO/MainProcess] Received task: Reminder.tasks.send_mail_reminder[7b14ef7b-c123-42c8-90d8-2baf4122963a] eta:[2016-08-04 23:24:00+05:30]
[2016-08-04 23:24:00,895: INFO/Worker-3] Reminder.tasks.send_mail_reminder[7b14ef7b-c123-42c8-90d8-2baf4122963a]: Send Email
[2016-08-04 23:24:00,920: INFO/MainProcess] Task Reminder.tasks.send_mail_reminder[7b14ef7b-c123-42c8-90d8-2baf4122963a] succeeded in 0.0263162209994s: None
当我从 Django shell 发送电子邮件而不使用 celery 时,它正在运行。当我这样做的时候,它也在进行
mail_test.py
from datetime import datetime,time
from Reminder.models import Reminder
import arrow
t = time(23,35)
date = datetime.today().date()
a = Reminder.objects.create(message="Hello world",date=date,time=t,email="abc@gmail.com",completed=False)
from Reminder.tasks import send_mail_reminder
# b = send_mail_reminder(a.id)
# print "b:",b
date_time = datetime.combine(a.date,a.time)
reminder_time = arrow.get(date_time).replace(tzinfo=a.time_zone.zone)
c = send_mail_reminder.apply_async((a.id,),eta=reminder_time, serializer='json')
print "c:",c
然后在终端执行以下命令,在celery中添加一个任务,执行成功。
./manage.py shell < mail_test.py
当我使用 post_save 信号时,它也按预期工作。
解决了。我使用 post_save 信号调用任务并使用 task_id.
保存@receiver(post_save, sender=Reminder)
def send_email_signal(sender,instance, created, **kwargs):
if not created:
return
self = instance
date_time = datetime.combine(self.date,self.time)
reminder_time = arrow.get(date_time).replace(tzinfo=self.time_zone.zone)
from .tasks import send_sms_reminder, send_mail_reminder
result = send_mail_reminder.apply_async((self.id,),eta=reminder_time, serializer = 'json')
if result.id:
instance.task_id = result.id
instance.save()