Управление долгосрочными задачами в приложении Aiohttp - PullRequest
1 голос
/ 30 апреля 2019

У меня есть веб-приложение в Aiohttp.

Как управлять долгосрочными задачами? Я вижу этот сценарий. Это плохо или хорошо?

  1. Пользователь делает запрос для некоторых длительных задач.
  2. Задача создания сервера с new_task = asyncio.create_task() Сгенерируйте uuid для нового задания и сохраните все в dict:
new_task = asyncio.create_task()
uuid_task = uuid.uuid4()
tasks_set.update({
    uuid_task: new_task
})
  1. Отправить ответ клиенту со статусом 202 Принят и UUID задачи.
  2. Через некоторое время пользователь делает запрос с заданием uuid для запроса статуса задания.
  3. Сервер ищет в tasks_set задание и получает его статус:
task = tasks_set.get(uuid_from_client)
if not task:
    raise TaskNotFound # send error, 404 for example
if not task.done():
    # task is not done yet
    answer_to_client('task is not done')
    return
else:
    answer_to_client('task is done. Result: ', task.result())
    tasks_set.pop(uuid_from_client)

Но я также должен управлять таймаутом для задач (пользователь ушел, и мы должны остановить его задачу). Любое предложение?

1 Ответ

1 голос
/ 30 апреля 2019

Но я также должен управлять таймаутом для задач

Вы можете использовать asyncio.wait_for, чтобы добавить таймаут к любой сопрограмме. Вместо:

# run coroutine in a new task
new_task = asyncio.create_task(coroutine(...))

Вы можете использовать:

# run coroutine in a new task, for no longer than 10s
new_task = asyncio.create_task(asyncio.wait_for(coroutine(...), 10)

new_task.done() будет истинным как в случае завершения сопрограммы, так и в случае истечения времени ожидания. Вы можете проверить время ожидания, протестировав new_task.done() and new_task.exception() is asyncio.TimeoutError.

...