我正在使用芹菜将任务发送到远程服务器并尝试将结果返回。使用远程服务器上的update_state方法不断更新任务状态。
我正在使用
发送任务if Auth.auth().currentUser != nil {
// User is signed in.
// ...
} else {
// No user is signed in.
// ...
}
获取芹菜任务的结果是一个阻止调用,我不希望我的django应用程序等待结果和超时。
所以我尝试运行另一个芹菜任务来获得结果。
app.send_task('task_name')
但它会导致以下错误。
@app.task(ignore_result=True)
def catpure_res(task_id):
task_obj = AsyncResult(task_id)
task_obj.get(on_message=on_msg)
此错误是否有解决方法?我是否必须运行守护进程才能获得结果?
答案 0 :(得分:8)
使用allow_join_result。请参阅下面的代码段。
@app.task(ignore_result=True)
def catpure_res(task_id):
task_obj = AsyncResult(task_id)
with allow_join_result():
task_obj.get(on_message=on_msg)
注意:正如其他答案中所提到的那样,它可能会导致性能问题甚至死锁,但如果您的任务编写得很好并且不会导致意外错误,那么它应该像魅力一样工作。
答案 1 :(得分:2)
正如您的标题所解释的那样,在任务中调用get
是一种不好的做法,可能导致死锁。
相反,您可以检查任务状态,并在其准备就绪时get
结果:
result = catpure_res.AsyncResult(task_id, app=app)
if result.ready():
return result.get()
return result.state
您可以将上述代码段包装在一个函数中,并每隔x秒请求一次。
编辑:关注您的评论:
您可以改为使用result.state
,并将retry
机制与countdown
一起使用,直到任务result.state == SUCCESS
。
您可以添加celery beat
来运行定期任务,检查主要任务是否结束。
请注意,使用如此繁重的任务(持续时间很长)也是一种不好的做法。考虑将其分解为一个小任务并使用canvas来组合它们。