让芹菜等待任务完成

Posted

技术标签:

【中文标题】让芹菜等待任务完成【英文标题】:Make celery wait for task to finish 【发布时间】:2020-07-09 17:57:03 【问题描述】:

我希望 celery 等待特定任务完成,因此我在 celery 本身旁边安装了 celery-results-backend。但我不明白我必须如何编写任务调用才能等待,因为我目前收到以下错误:

example_task() missing 1 required positional argument: 'user_pk'

views.py:

def example(request):
    user = request.user
    if request.method == 'GET':
        result = example_taks.apply_async(user_pk=user.pk)
        result_output = result.wait(timeout=None, interval=0.5)
        return redirect('something')
    else:
        args = 'user': user
        return redirect(reverse('something'), args)

tasks.py:

def example_task(user_pk):
    user = User.objects.get(pk=user_pk)
    try:
       ...

以前我是这样称呼会谈的:

def example(request):
    user = request.user
    if request.method == 'GET':
    example_task.delay(request.user.pk)
    ...

这工作正常,但没有等待任务完成。

如果我这样做:

result = allocate_new_bch_address.apply_async(request.user.pk)

我也收到一个错误:

example_task() argument after * must be an iterable, not UUID

【问题讨论】:

如果您正在等待任务完成,为什么还要使用 celery?直接在视图中运行方法会更好 这可能会彻底扼杀我使用 k8s 扩展应用程序的想法 只是扩大 django 工人的数量而不是 celery 工人的数量? 嗯,这可能不是一个好主意。如果您有一个大型应用程序,您可能不希望使用相同的容器来处理您的任务,因为它们已经在处理用户请求,此外没有选项可以设置 Web 实例的数量或 celery 工作者实例的数量。不喜欢这个主意,对不起。我们可以专注于这个问题吗? 等待任务完成将占用您的 django 工作人员之一,因为它将被阻止直到任务完成... 【参考方案1】:

首先,您使用 apply_async() 错误。该函数接受您的任务参数打包为元组 (args) 和字典 (kwargs),如 here 所示。这是因为您可以指定定义任务应如何运行的附加参数。另一方面,delay()only accepts your task's args and kwargs。在大多数情况下,delay() 就足够了。

您可以这样做:

 example_taks.apply_async(kwargs="user_pk":user.pk)

或者这个:

example_tasks.delay(user_pk=user.pk)

您也可以使用位置参数,但我建议尽可能使用 kwargs。

其次,一旦提交就等待异步任务违背了 Celery 的目的。要等待任务完成,您需要在结果上调用 get():

result = example_tasks.apply_async(kwargs="user_pk":user.pk)
result_output = result.get()

【讨论】:

切换到 gunicorn 生产服务器后,您的建议似乎会导致以下错误:***.com/questions/61155267/… 任何想法?

以上是关于让芹菜等待任务完成的主要内容,如果未能解决你的问题,请参考以下文章

Celery-一个会做异步任务,定时任务的芹菜

如何在 Django 中等待芹菜任务的结果

芹菜作为网络发布/订阅事件

芹菜工人在当前任务完成后不会再接新任务

芹菜:列出所有任务,计划的,活动的*和*完成

如何在不杀死未完成的芹菜任务的情况下重新启动heroku应用程序