我有以下要求。我正在创建一个网络应用程序(没有前端),它将接收帖子和获取请求。它的功能如下。客户端将在URL上发布一个帖子,触发一个庞大且耗时的任务。客户端还可以发出Get请求并检索taks的结果。
我想用芹菜来开始这项任务。这项任务是一项很大的算术运算。我的问题是如何通知客户端他触发的任务已经完成,他可以检索结果。
所以我是这样想的:
client ->posts to web app -> web app starts task to celery -> request closed
web app notifies -> client triggered task # what is the proper way
client -> get request to web app -> web app returns result
我知道没有一个合适的方法,所以我会更具体一点。目前,该任务将由另一个烧瓶应用程序自动触发。是否有一种方法可以自动通知烧瓶应用程序任务已完成,并获取结果并将其存储在自己的数据库中?第二个问题是,即使客户端是烧瓶应用程序、安卓应用程序、IOS应用程序等,最通用的解决方案是什么。
我之所以这么问,是因为我曾就api是否将结果发布回客户端或客户端是否应该负责检查并获得结果进行过辩论。
我过去也不得不做出类似的决定,在完成长时间运行的芹菜任务后,需要更新客户端。有很多不同的方法来设计系统来解决这个问题:
- 带轮询的状态端点-这是最简单的解决方案。在烧瓶中暴露一个端点,该端点返回作业的状态,并简单地从客户端轮询。然而,有几件事需要注意,即客户端的数量和轮询频率。如果您的客户端太多或轮询过于频繁,则可能会遇到性能问题。如果你有几个客户端,不需要即时状态更新,这是理想的选择
- WebSockets-在客户端和flask服务器之间打开一个WebSocket,并在任务完成时使用它来推送更新。这种方法将更好地扩展到多个客户端,并允许近乎即时的通知
- 回调URL-您提到客户端是Flask应用程序。您可以在客户端服务器上公开一个回调路由,并在启动任务时将其提供给芹菜。任务完成后,Celery可以POST到回调URL,这将通知客户端
至于最通用的解决方案,要么是状态端点,要么是WebSockets-安卓&iOS内置了HTTP功能,可以使用库处理WebSocket。另一方面,回调URL解决方案是特定于Flask的。