9

In the project, I try to poll task.state of a long running task and update its running status. It worked in the development, but it won't work when I move the project on production server. I kept getting 'PENDING' even I can see the task started on flower. However, I can still get the results updated when the task finished, which when task.state == 'SUCCESS'. I use python 2.6, Django 1.6 and Celery 3.1 in the production, result backend AMQP.

@csrf_exempt
def poll_state(request):
    data = 'Fail'

    if request.is_ajax():
            if 'task_id' in request.POST.keys() and request.POST['task_id']:
                    task_id = request.POST['task_id']
                    email = request.POST['email']
                    task = AsyncResult(task_id)
                    print "task.state=", task.state
                    if task.state == 'STARTED':
                            task_state = 'Running'
                            data = 'Running'
                            #data = 'Running'
                    elif task.state == 'PENDING' or task.state == 'RETRY':
                            task_state = 'Waiting'
                            data = 'Pending'
                    elif task.state == 'SUCCESS':
                            task_state = 'Finished'
                            if task.result:
                                    data = task.result
                            else:
                                    data = 'None'

                    else:
                            task_state = task.state
                            data = 'Error'
                            print 'data status =', task_state
            else:
                    task_state = task.state
                    data = 'Error'
    else:
            task_state = task.state
            data = "Error"

    json_data = json.dumps({'task_state':task_state, 'task_data':data})

 return HttpResponse(json_data, mimetype='application/json')

on another note, flower always show the workers' status offline, but tasks status were correct. When using celery events 3.1.12 (Cipater), it shows correct worker status.

fasouto
  • 4,386
  • 3
  • 30
  • 66
user3795121
  • 93
  • 1
  • 4

3 Answers3

11

For Celery 4.1.0 and Django 1.11.7 this is what you need in the config.py file:

Correct:

task_track_started = True

Also Correct:

CELERY_TASK_TRACK_STARTED = True

WRONG!:

CELERY_TRACK_STARTED = True

Just took me 2 hours to figure out. Hope this serves somebody in the near future

radzia2
  • 339
  • 4
  • 19
3

It's probably related to CELERY_TRACK_STARTED setting. Quoting the docs:

CELERY_TRACK_STARTED

If True the task will report its status as “started” when the task is executed by a worker. The default value is False as the normal behaviour is to not report that level of granularity. Tasks are either pending, finished, or waiting to be retried. Having a “started” state can be useful for when there are long running tasks and there is a need to report which task is currently running.

Maybe you have CELERY_TRACK_STARTED = True in your development settings, but not in production ?

Seb D.
  • 5,046
  • 1
  • 28
  • 36
  • 3
    I had 'CELERY_TRACK_STARTED = True' in my settings.py and I set celeryconfig.py with os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings'). The problem is that AsyncResult(task_id).state always return 'PENDING' status so my template cannot update to 'STARTED' when the task started. But both flower and celery events monitor showed task started correctly. Very confused. – user3795121 Jul 02 '14 at 21:53
  • Can you run on the terminal where your prodution is running `celery inspect conf --app your_app_name` just to check if the setting `CELERY_TRACK_STARTED` were well loaded? – Seb D. Jul 03 '14 at 07:53
  • That's the problem! app.conf is not updated until I set it explicitly in tasks.py. I guess os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') has not been working. I am still confused about why this happened. – user3795121 Jul 03 '14 at 14:23
0

For folks using django-celery-email -- it's necessary to have the following set:

CELERY_EMAIL_TASK_CONFIG = {
    'name': 'djcelery_email_send',
    'ignore_result': False,
}

CELERY_TASK_TRACK_STARTED = True
CELERY_EMAIL_CHUNK_SIZE = 1 

I believe the similar problems I was having were due to having 'ignore_result' be set to True. From the django-celery-email docs:

results will be a list of celery AsyncResult objects that you may ignore, or use to check the status of the email delivery task, or even wait for it to complete if want. You have to enable a result backend and set ignore_result to False in CELERY_EMAIL_TASK_CONFIG if you want to use these. You should also set CELERY_EMAIL_CHUNK_SIZE = 1 in settings if you are concerned about task status and results.

Hopefully this helps other folks, similarly also spent several hours figuring this out...

orange1
  • 2,871
  • 3
  • 32
  • 58