Вот мои настройки:
- Джанго 1,3
- сельдерей 2.2.6
- Джанго-сельдерей 2.2.4
- djkombu 0.9.2
В моем файле settings.py у меня есть
BROKER_BACKEND = "djkombu.transport.DatabaseTransport"
т.е. Я просто использую базу данных для постановки задач в очередь.
Теперь к моей проблеме: у меня есть задание, инициированное пользователем, которое может занять несколько минут. Я хочу, чтобы задача выполнялась только один раз для каждого пользователя, и я буду кэшировать результаты задачи во временном файле, поэтому, если пользователь снова запускает задачу, я просто возвращаю кэшированный файл. У меня есть код, который выглядит следующим образом в моей функции просмотра:
task_id = "long-task-%d" % user_id
result = tasks.some_long_task.AsyncResult(task_id)
if result.state == celery.states.PENDING:
# The next line makes a duplicate task if the user rapidly refreshes the page
tasks.some_long_task.apply_async(task_id=task_id)
return HttpResponse("Task started...")
elif result.state == celery.states.STARTED:
return HttpResponse("Task is still running, please wait...")
elif result.state == celery.states.SUCCESS:
if cached_file_still_exists():
return get_cached_file()
else:
result.forget()
tasks.some_long_task.apply_async(task_id=task_id)
return HttpResponse("Task started...")
Этот код почти работает. Но я сталкиваюсь с проблемой, когда пользователь быстро перезагружает страницу. Существует задержка в 1-3 секунды между тем, когда задача ставится в очередь, и когда задача, наконец, снимается с очереди и передается работнику. В течение этого времени состояние задачи остается в состоянии ОЖИДАНИЯ, в результате чего логика представления запускает дублирующую задачу.
Мне нужен какой-то способ сказать, было ли задание уже отправлено в очередь, поэтому я не заканчиваю отправлять его дважды. Есть ли стандартный способ сделать это в сельдерее?