我在Django中有一个同步API,它可以发出多个外部请求出于性能原因,我将对其进行折旧并切换到异步模型:该请求将触发多个芹菜子任务,客户端必须获取任务状态,直到任务完成。
但是,当我们需要执行向后兼容性时,我不能马上摆脱现有的API。为此,我打算在异步任务周围实现一个同步包装器。在我看来,向后兼容的api必须这样做:
启动异步任务
睡觉
刷新对象,如果完成,退出
或循环
大致如下:
task = MyTask.objects.create(...).run() # Will span multiple parallel sub-tasks
while task.is_ongoing(): # Check if all sub-tasks are completed
sleep(1)
task.refresh_from_db()
当然,从django的角度来看这是一个非常糟糕的设计,但是我认为没有其他方法可以确保与同步api的向后兼容性。如果django支持
async
会更好,但我还没有找到一种方法来挂起当前线程而不阻塞所有线程。当然,我可以在同步API中同步运行所有任务,但这会破坏并行化“长时间运行”任务的目的(每个任务几秒钟)。
因此我有两个问题:
还有别的办法吗?
在Django的主线上睡觉最不坏的方式是什么?是
sleep
还是有更好的选择? 最佳答案
一个比循环更好的方法是使用sleep
触发芹菜任务,而不是Task.apply
。apply_async
将阻塞,直到任务完成。