Вызов функций синхронизации из асинхронной функции

Я пытаюсь портировать flask приложение для quart использовать asyncio, Я не думаю, что мой нынешний подход работает, так как вся моя цепочка функций написана без учета асинхронности - учтите следующее:

def long_running_task(task):
    result = some_synchronous_function(task)
    return result

@app.route('/<task>', methods=['GET'])
async def do_task(task):
    ok = await long_running_task(task)
    if ok:
        return (ok.result)
    else:
        return ('Something went wrong')

Если long_running_task и вся его цепочка вызовов функций не объявлена ​​как asyncдействительно ли я получаю какую-либо выгоду от того, что мой маршрут объявлен async?

1 ответ

Решение

Чтобы запустить блокирующую синхронную функцию из asyncio, не блокируя основной цикл событий, вы можете использовать loop.run_in_executor() запустить функцию блокировки в ThreadPoolExecutor или же ProcessPoolExecutor ` (т.е. в своем собственном потоке или процессе).

Внутри асинхронной функции вы хотите вызвать ее:

loop = asyncio.get_event_loop()

result = await loop.run_in_executor(None, long_running_task, task)

Первый аргумент None это сказать ему использовать исполнителя по умолчанию для цикла. очевидно do_task() все равно придется ждать result для завершения, но пока он ожидает, другие асинхронные задачи смогут выполняться в цикле обработки событий.

Другие вопросы по тегам