Задача довольно тривиальная как по мне, но не могу понять как правильно это сделать.
Предположим на сервер приходит запрос от пользователя.
Необходимо асинхронно залезть в базу и синхронно что-то посчитать.
Но если выполнить код ниже, он очевидно сначала будет ждать возвращения функции async_io, а только потом начнет компутинг.
async def async_io():
print("async_io start")
result = await asyncio.sleep(1, result=500)
print("async_io end")
return result
def sync_calculating():
print("sync_calculating start")
res = 0
for i in range(1000):
res += 1
print("sync_calculating end")
return res
async def task():
print("Task start")
res_async = await async_io()
res_sync = sync_calculating()
print("Task end")
return res_async + res_sync
loop = asyncio.get_event_loop()
loop.create_task(task())
loop.run_forever()
В идеале я бы хотел в функции async_io дойти до места где происходит await, и потом начать синхронный sync_calculating.
Соответственно к концу подсчетов у меня уже вернулись бы данные из базы и осталось их только вернуть.
Нечто подобное можно сделать если переписать task примерно так:
async def task():
print("Task start")
res_async = asyncio.ensure_future(async_io())
await asyncio.sleep(0.1)
res_sync = sync_calculating()
res_async = await res_async
print("Task end")
return res_async + res_sync
То есть планировщик добавит таск async_io в очередь, и когда дойдет до await asyncio.sleep он вызовет async_io.
Но как-то очень криво.
res_async = await res_async нужен для того чтобы убедиться что корутина выполнилась к этому моменту, и подождать её в противном случае
Нельзя как-то триггернуть выполнение async_io, дойти до await внутри него и вернуться выполнять синхронный код?