以下是伪代码的基本结构:
# views.py
from tasks import run_task
def view_task():
run_task.delay()
return render(request, 'template.html')
# tasks.py
from compute_module import compute_fct
@shared_task
def run_task():
result = compute_fct()
# how to catch status update messages from compute_module while compute_fct is running??
if result == 'error':
handle_error()
else:
handle_succes()
# compute_module
import pandas as pd
def compute_fct():
# send message: status = loading file
df = pd.read_csv('test.csv')
# send message: status = computing
val = df['col'].mean()
if val is None:
return {'status':'error'}
else:
return {'status':'success','val':val}
我理想的情况是:
compute_module.py
模块使用 Python 的本地记录器。出于职责分离的考虑,我希望将日志记录尽可能通用,并使用标准的 Python/Django 记录器。但它们似乎没有被设计为向前端发送消息。- celery 任务处理日志,而不是在 stdout 上显示它们,将它们重定向到 pusher
- 前端 JS 显示和处理消息
可能有标准的方法在 celery worker 和前端之间通信,但我不知道。这种情况可能经常发生,我很惊讶实现起来如此困难。在某种程度上,RabbitMQ 消息队列或 AWS SNS 应该为此而设计。以下是我查看过但感觉都不太好用的资源,也许只是我混淆了。
日志记录:这似乎更多是关于服务器端日志记录,而不是向用户发送消息。
- http://docs.celeryproject.org/en/latest/userguide/tasks.html#logging
- https://docs.djangoproject.com/en/2.0/topics/logging/
- http://oddbird.net/2017/04/17/async-notifications/
- https://www.google.com/search?q=celery+worker+send+message+to+front+end
Celery cam 似乎是关于监控任务的管理员,而不是向用户发送消息。
我喜欢 pusher,但我不希望 compute_module.py
处理它。例如,我更愿意在 compute_module.py
内部不进行任何 pusher.com 集成。我可以传递一个已经被实例化的 pusher 对象,使模块只需推送消息,但我仍然希望它是通用的。