我最近一直在研究芹菜。我以前没有经常使用它,但我想用来以异步方式处理对我的数据库的 sql 查询,以便 1 个数据点不会阻止网页加载。(这是一个很好的用例吗?
我已经实现了如下所示的东西,但它似乎是多余的,可能有更好的方法来做到这一点。我非常感谢一些批评和建议。
示例代码:
@celery.task
def _get_player_name(player_tag):
player = PlayerStatsCurrent.query.filter_by(player_tag=player_tag).first()
return player.player_name
def get_player_name(player_tag):
result = _get_player_name.delay(player_tag)
while not result.ready():
time.sleep(0.5)
player_name = result.get()
return player_name
在上面的示例中,我的网页调用get_player_name
以及其他一些看起来相似但计算成本更高的函数。
代码有效。我按预期得到输出。我只是想让它更"pythonic",因为它现在看起来并不干燥,而且我不擅长芹菜知道如何做到这一点。提前感谢您的帮助。
选择何时将任务卸载到后台工作线程是一个有点主观的问题,但在上面示例这样的情况下,我会让查询发生在与 Web 请求相同的进程或线程中。
您在上面显示的内容很可能需要几毫秒。 另一方面,如果你有一个需要 10 秒才能运行的查询,那么考虑它是否应该是一个后台任务是合理的,当然也应该需要几分钟。
我要说的另一点是,当您将_get_player_name
作为 Celery 任务运行时,get_player_name
函数会阻止等待它完成。 如果 Web 处理程序正在调用后一个函数,则 Web 服务器进程/线程在任务期间仍处于阻塞状态。
当我有一个启动后台任务的终结点时,我会让它创建一个作业记录,并将该记录的 ID 返回到前端。 然后,前端可以使用该作业 ID 定期轮询,以查看任务是否已完成。 如果您的服务器支持 websockets,您也可以在这种情况下使用 websockets。