AsyncResult(task_id)返回"PENDING"状态,即使任务已开始
在这个项目中,我尝试去检查一个长时间运行的任务的状态,并更新它的运行状态。在开发环境中这个方法是有效的,但当我把项目放到生产服务器上时,就不行了。我一直看到状态是'PENDING',即使我能在flower上看到任务已经开始。不过,当任务完成时,我还是能获取到更新的结果,这时任务状态是'SUCCESS'。我在生产环境中使用的是Python 2.6、Django 1.6和Celery 3.1,结果后端是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')
另外,flower总是显示工作者的状态为离线,但任务的状态是正确的。当使用celery events 3.1.12(Cipater)时,它显示的工作者状态是正确的。
3 个回答
对于使用 django-celery-email
的朋友们,必须设置以下内容:
CELERY_EMAIL_TASK_CONFIG = {
'name': 'djcelery_email_send',
'ignore_result': False,
}
CELERY_TASK_TRACK_STARTED = True
CELERY_EMAIL_CHUNK_SIZE = 1
我认为我遇到的类似问题是因为 'ignore_result'
被设置为 True
。根据 django-celery-email
的文档:
结果将是一个包含 celery AsyncResult 对象的列表,你可以选择忽略它们,或者用它们来检查邮件发送任务的状态,甚至可以等到它完成。如果你想使用这些功能,你需要启用结果后端,并在 CELERY_EMAIL_TASK_CONFIG 中将 ignore_result 设置为 False。如果你关心任务的状态和结果,还应该在设置中将 CELERY_EMAIL_CHUNK_SIZE 设置为 1。
希望这能帮助到其他人,我也花了好几个小时才搞明白这个问题……
对于Celery 4.1.0和Django 1.11.7,你在config.py文件中需要这样设置:
正确的写法:
task_track_started = True
也可以这样写:
CELERY_TASK_TRACK_STARTED = True
错误的写法:
CELERY_TRACK_STARTED = True
我花了两个小时才搞明白这个,希望这能帮助到将来需要的人。
这可能和 CELERY_TRACK_STARTED 这个设置有关。根据文档的说明:
CELERY_TRACK_STARTED
如果设置为 True,当任务被工作者执行时,它会报告状态为“已开始”。默认值是 False,因为正常情况下不需要报告这么详细的状态。任务通常只有三种状态:待处理、已完成或等待重试。设置“已开始”状态在处理一些需要很长时间的任务时会很有用,这样可以知道当前正在运行的是哪个任务。
也许你在开发环境中把 CELERY_TRACK_STARTED = True
设置了,但在生产环境中没有?