是否可以在没有轮询的情况下监控芹菜任务的状态?
例如,如果我有一个使用update_state
定期更新其状态的任务:
@task(bind=True)
def my_task(self):
for x in range(100):
time.sleep(1)
self.update_state(state='PROGRESS', meta={'x': x})
是否可以在没有轮询的情况下从另一个进程监视该状态?
答案 0 :(得分:2)
我自己还没有这样做,所以这不是一个完整的答案,但我有兴趣解决同样的问题。我有三个值得考虑的想法:
使用内置的handler states on_failure
,on_retry
和on_success
是否适用于您的用例?
另一个是子类Task
(这里的简单示例:Callback for celery apply_async)并添加on_*
处理程序,它们为您的自定义状态传递回调函数。也许这甚至不是必要的
最好的可能是write a custom event receiver。我认为这是他们的"Real-time Celery web-monitor"示例的工作原理。关于此的相关SO帖子是:Implementing Twisted style local multiple deferred callbacks in Celery。
答案 1 :(得分:1)
这取决于您的经纪人/后端。如果他们使用pub / sub,那么您的进程将不需要轮询任务状态。如果他们不这样做,那么你将需要进行轮询(或者更普遍的是涉及发送要求状态的消息的过程)。
我认为芹菜和红葡萄都有这种能力。
答案 2 :(得分:0)
假设您要跟踪生产者的进度,您需要使用事件监控API。另一个apis,处理程序和信号,只在工人身上运行;所以没有用于跟踪制作人的进度。
查看文档中名为“监视和管理指南”的部分,您应该能够几乎逐字地运行示例代码(对于事件接收器)。但是,它没有提到,也需要为工作人员启用事件生成。你工作的-E参数将解决这个问题。
答案 3 :(得分:0)
通过on_message
回调,您可以指定在任务更改状态时调用的函数。
例如,以下任务在被调用时发送自定义PROGRESS
状态。
from celery import Celery
app = Celery("tasks", broker="pyamqp://guest@localhost//", backend="rpc://")
@app.task(bind=True)
def square(self, x):
self.update_state(state="PROGRESS")
return x**2
您可以看到这就是呼叫者。
>>> tasks.square.delay(5).get(on_message=print)
{'task_id': 'f63eb965-3cdc-4bcc-a5e1-b0bb2149c376', 'status': 'PROGRESS', 'result': None, 'traceback': None, 'children': []}
{'task_id': 'f63eb965-3cdc-4bcc-a5e1-b0bb2149c376', 'status': 'SUCCESS', 'result': 25, 'traceback': None, 'children': []}
25
如果您想要一个更复杂的示例,我有一个gist,它使用Celery在更新进度条时对文件目录进行并行复制。