我有一个主芹菜任务,它启动多个子任务(数千个(执行多个操作(每个子任务相同的操作(。
我想要的是,从主要的芹菜任务实时跟踪每个动作,每个子任务完成了多少,失败了多少。
总之!
- 主要任务:接收对象列表,以及每个对象要执行的操作列表。
- 对于每个对象,将启动一个子任务来执行对象的操作。
- 当所有子任务都完成时,主任务就完成了
所以我需要从主任务中知道子任务的实时进度。
我正在开发的应用程序使用的是 django/angularJs,我需要在前端异步显示实时进度。
我是芹菜的新手,我很困惑,不知道如何实现这一点。
任何帮助将不胜感激。提前谢谢。
我以前做过,这里有太多的代码要放进去,所以请允许我简单地提一下大纲,因为我相信你可以照顾到实际的实现和配置:
基于 Socket.io 的微服务,用于将实时事件发送到浏览器
首先,Django 是同步的,所以用它做任何实时的事情并不容易。
所以我求助于一个 socket.io 的过程。你可以说它是一个微服务,只侦听 Redis 支持的"通道",并向侦听给定通道的浏览器客户端发送通知。
芹菜 -> 雷迪斯 -> Socket.io -> 浏览器
我这样做是为了用一个芹菜任务 ID 标识每个频道。因此,当我从浏览器触发芹菜任务时,我会获得任务 ID,保留它并开始通过该通道侦听来自 socket.io 的事件。
按时间顺序,它看起来像这样:
- 发射芹菜任务,获取ID
- 将 ID 保留在客户端应用中,打开 socket.io 通道以侦听更新
- 芹菜任务向 Redis 发送消息,这将触发 socket.io 事件
- Socket.io 将消息实时中继到浏览器
报告进度
至于任务状态的实际更新,我只是让它让 Celery 任务在其代码中在 Redis 上发送一条消息,例如 {'done': 2, 'total_to_be_done': 10}
(为了表示一个任务经历了 10 个步骤中的 2 个,进度为 20%,我更喜欢发送这两个数字以获得更好的 UI/UX(
import redis
redis_pub = redis.StrictRedis()
channel = 'task:<task_id>:progress'
redis_pub.publish(channel, json.dumps({'done': 2, 'total_to_be_done': 10}))
在此处查找有关使用 Python 在 Redis 上发布消息的文档
AngularJS/Socket.io integration
您可以使用或至少从像angular-socket-io这样的库中获得一些灵感