Проблема
Я сегментировал долговременную задачу в логических подзадачах, поэтому я могу сообщать результаты каждой подзадачи по мере ее завершения. Тем не менее, я пытаюсь сообщить о результатах задачи, которая никогда не будет успешно завершена (вместо этого она даст значения, как она есть), и я изо всех сил стараюсь сделать это с помощью моего существующего решения.
Фон
Я создаю веб-интерфейс для некоторых программ Python, которые я написал. Пользователи могут отправлять задания через веб-формы, а затем проверять их работу.
Скажем, у меня есть две функции, каждая из которых доступна через отдельные формы:
-
med_func
: Выполняется ~ 1 минута, результаты передаются наrender()
, который создает дополнительные данные. -
long_func
: возвращает генератор. Каждыйyield
занимает порядка 30 минут и должен сообщаться пользователю. Есть так много уроков, мы можем считать этот итератор бесконечным (завершение только тогда, когда отменено).
Код, текущая реализация
С med_func
я сообщаю результаты следующим образом:
При отправке формы я сохраняю AsyncResult
в сеансе Django:
task_result = med_func.apply_async([form], link=render.s())
request.session["task_result"] = task_result
Представление Django для страницы результатов обращается к этому AsyncResult
. Когда задача завершена, результаты сохраняются в объект, который передается как контекст шаблону Django.
def results(request):
""" Serve (possibly incomplete) results of a session latest run. """
session = request.session
try: # Load most recent task
task_result = session["task_result"]
except KeyError: # Already cleared, or doesn't exist
if "results" not in session:
session["status"] = "No job submitted"
else: # Extract data from Asynchronous Tasks
session["status"] = task_result.status
if task_result.ready():
session["results"] = task_result.get()
render_task = task_result.children[0]
# Decorate with rendering results
session["render_status"] = render_task.status
if render_task.ready():
session["results"].render_output = render_task.get()
del(request.session["task_result"]) # Don't need any more
return render_to_response('results.html', request.session)
Это решение работает только тогда, когда функция фактически завершается. Я не могу объединить логические подзадачи long_func
, потому что есть неизвестное число yield
(каждая итерация цикла long_func
может не дать результата).
Вопрос
Есть ли разумный способ доступа к предоставленным объектам из чрезвычайно долговременной задачи Сельдерея, чтобы они могли отображаться до истощения генератора?