让 celery 等待任务完成

3 django task celery

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

example_task() missing 1 required positional argument: 'user_pk'
Run Code Online (Sandbox Code Playgroud)

视图.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)
Run Code Online (Sandbox Code Playgroud)

任务.py:

def example_task(user_pk):
    user = User.objects.get(pk=user_pk)
    try:
       ...
Run Code Online (Sandbox Code Playgroud)

之前我是这样称呼这次会谈的:

def example(request):
    user = request.user
    if request.method == 'GET':
    example_task.delay(request.user.pk)
    ...
Run Code Online (Sandbox Code Playgroud)

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

如果我这样做:

result = allocate_new_bch_address.apply_async(request.user.pk)
Run Code Online (Sandbox Code Playgroud)

我也收到一个错误:

example_task() argument after * must be an iterable, not UUID
Run Code Online (Sandbox Code Playgroud)

小智 10

首先,你用apply_async()错了。该函数接受打包为元组 (args) 和字典 (kwargs) 的任务参数,如下所示。这是因为您可以指定其他参数来定义任务应如何运行。另一方面,delay() 仅接受任务的 args 和 kwargsdelay()在大多数情况下就足够了。

您可以这样做:

 example_taks.apply_async(kwargs={"user_pk":user.pk})
Run Code Online (Sandbox Code Playgroud)

或这个:

example_tasks.delay(user_pk=user.pk)
Run Code Online (Sandbox Code Playgroud)

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

其次,提交异步任务后立即等待它违背了 Celery 的目的。要等待任务完成,您需要对结果调用get() :

result = example_tasks.apply_async(kwargs={"user_pk":user.pk})
result_output = result.get()
Run Code Online (Sandbox Code Playgroud)