In a django app I'm running async tasks and would like to show progress, errors etc to the user. If there are errors, the user should be redirect to a page where additional input or some action is required to fix the problem. What is the best way to communicate from the celery work back to the front end?
Here's a basic structure in pseudo code:
# 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}
What I would ideally want:
compute_module.py
module uses python native logger. By separation of duties I want to keep the logging as generic as possible and use the standard python/django loggers. But they don't seem to be designed to send messages to front end.- celery task somehow handles the logs and instead of displaying them on stdout redirects them to pusher
- front-end js shows and handles the messages
There might be standard ways of communicating between celery worker and front end that I'm not aware off. this scenario must happen often and I am surprised it's so difficult to implement. in a way the rabbitmq message queue or aws sns should be designed for this. below are resources that I looked at but don't feel either of them work very well but maybe I am just confused.
logging: this seems to be more about logging on the server side, not sending messages to user
- 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 seems to be about admin monitoring tasks, not sending messages to user
pusher I like but I don't want to have compute_module.py
deal with it. That is For example I would prefer not to do any pusher.com integration inside compute_module.py
. Guess I could pass a pusher object that has already been instantiated so the module can just push messages but again I would prefer it to be generic