如何在 Django 中等待芹菜任务的结果
Posted
技术标签:
【中文标题】如何在 Django 中等待芹菜任务的结果【英文标题】:How to wait for results from a celery task in Django 【发布时间】:2019-06-12 12:28:39 【问题描述】:我有一个 celery 任务,它将数据发送到另一个服务。我已将 celery 任务 send_inventory_request
添加到 RequestSupplyStock
基于类的视图中。当我发帖时,我应该首先从 celery 任务中获取结果,然后继续并返回响应。我想先等待 celery 任务的结果,然后从 post 方法返回响应,这是实现此目的的正确方法。
@app.task
def send_inventory_request(payload,token):
auth = 'authorization':token
HEADERS.update(auth)
url = PROCUREMENT_SUPPLY_STOCK_REQUESTS_URL
res = requests.post(url,json=payload,headers=HEADERS)
inventory_request_data = res.json()
x= logger.info('Supply Stock Request 0 + 1'.format(payload,token))
print(x)
return inventory_request_data
查看
class RequestSupplyStock(generics.CreateAPIView):
def post(self, request, format=None):
........
send_inventory_request.delay(payload,get_token(request))
.........
return Response(status=status.HTTP_201_CREATED)
【问题讨论】:
Celery 的重点是让您不必等待长时间运行的任务。如果需要等待,不要使用Celery,直接在视图中进行。 如果你依赖 celery 任务结果,那么肯定没有使用 celery 任务。但是,如果您需要针对某些特殊情况执行此操作,只需简单地调用该任务而不使用 .delay 。我的意思是`send_inventory_request.(payload,get_token(request))`。这将返回您的结果。 我需要将物品发送到另一个服务我的方法是使用任务将库存请求发送到另一个服务。我绝对同意我不需要等待结果,但我可以让他们排队,如果有问题让他们重试。 那么为什么不简单地使用 try ,除了阻止或重试装饰器,如果你没有收到你想要的响应,只需简单地重试你预先定义的最大重试限制。 如果要使用 celery 任务,正确的解决方案是将任务 ID 作为响应值返回,并提供另一个入口点来获取任务的状态(以及完成后的结果)——客户端将负责轮询这个其他入口点。 【参考方案1】:你可以使用 celery wait ,但不推荐
在一个任务中等待任务可能会导致死锁。请阅读 避免启动同步子任务。
task = send_inventory_request.delay(payload,get_token(request))
result = task.wait(timeout=None, interval=0.5)
【讨论】:
【参考方案2】:正如其他人在评论中已经提到的那样,以同步方式等待结果违背了使用 celery 的目的,但如果您仍然需要等待结果,请不要delay
。
只需像普通方法一样调用任务,它就会同步运行并返回结果:
send_inventory_request(payload,get_token(request))
【讨论】:
是的,我想我会避免这种方法,并从文档中阅读更多关于 celery 的信息。 除非您需要在不同的工作人员上执行任务,否则这将起作用。在这种情况下,您必须使用延迟/等待的方法,否则任务将在本地执行。以上是关于如何在 Django 中等待芹菜任务的结果的主要内容,如果未能解决你的问题,请参考以下文章
Python Celery - 如何在其他任务中调用芹菜任务