【问题标题】:calling celery task with delay gets stuck延迟调用芹菜任务卡住了
【发布时间】:2018-08-23 19:32:13
【问题描述】:

一个 celery 任务定义如下:

from celery.decorators import task

@task(name="send_email")
def send_email(email, host):

这样调用时,Django 卡住了:

send_email.delay(email, host)

就像它不是异步运行一样,

我错过了什么?

这些是一些 celery 设置,它使用 redis 作为代理:

>>> settings.CELERY_ACCEPT_CONTENT
[u'application/json']
>>> settings.CELERY_BROKER_URL
u'redis://redis:6379/0'
>>> settings.CELERY_RESULT_BACKEND
u'redis://redis:6379/0'
>>> settings.CELERY_RESULT_SERIALIZER
u'json'
>>>

【问题讨论】:

  • 你能展示你定义你的芹菜应用程序的文件吗?正如docs 所建议的那样,该任务可能与特定应用程序无关
  • 当我运行 celery 时,我看到任务已注册,如下所示: celeryworker_1 | . website.tasks.send_email,所以应该是关联的

标签: python django celery


【解决方案1】:

我宁愿发表评论,但我首先需要 50 个代表,但我们需要函数的其余部分。除非您向我们展示您所做的一切,否则无法修复。因为你没有展示它,所以我会给你展示我的一个,希望它能让你清楚地知道你做错了什么。我有一些 celery 电子邮件函数,但它们只接受 1 个参数(来自对象的 id),并将值返回给调用它的函数。请注意,您还需要让 settings.py 包含正确的 EMAIL_BACKEND 等设置(如 EMAIL_HOST 等)。

但如果您只使用控制台,您唯一需要的电子邮件设置是EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'。只要您运行 celery 并且所有内容都指向正确的位置,下面的示例就可以使用它。

示例:

假设模型等已正确导入,因此 linter 没有显示错误,这一切都在一个文件中。

@task
def order_created(order_id):
    """Task to send an email notification when an order is successfully created"""
    order = Order.objects.get(id=order_id)
    subject = 'Order number {}'.format(order.id)
    message = 'Dear {},\n\nYou have successfully made an order. Your order id is {}.'.format(order.first_name, order.id)
    mail_sent = send_mail(subject, message, 'you@your_email.com', [order.email])
    return mail_sent



def make_an_order(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save()
            for item in cart:
                OrderItem.objects.create(order=order, product=item['product'], price=item['price'], quantity=item['quantity'])
            cart.clear()
            order_created.delay(order.id)    # id is passed to celery function
            request.session['order_id'] = order.id
            return redirect(reverse('payment_app:process'))
    else:
        form = OrderCreateForm()  # instantiates form based on Order model.
        return render(request, 'orders_app/create.html', {'cart': cart, 'form': form})

【讨论】:

  • 您好,感谢您的回答,我基本上是在发送电子邮件,基本上是调用 BaseEmailMessage,电子邮件设置有效,因为当我调用 send_email(email, host) 时它有效,就在我调用 send_email.delay(电子邮件,主机)卡住了,可能是代理问题?
  • 嗯,这是一个线索......当你说你正在传递一个host,你是不是试图从 settings.py 覆盖 EMAIL_HOST?如果是,我看不到显示您的新 host 参数应该是什么的变量,也没有看到所有其他设置的密码。就像我说的那样,如果您显示其余代码会很好(只需对其进行编辑,以免显示重要细节),因为没有它几乎不可能修复。
  • 主机变量用于电子邮件模板上下文,而不是用于 EMAIL_HOST。
猜你喜欢
  • 1970-01-01
  • 2020-03-04
  • 2013-04-26
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多