让芹菜等待任务完成
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/… 任何想法?以上是关于让芹菜等待任务完成的主要内容,如果未能解决你的问题,请参考以下文章