Является ли асинхронный Python действительно асинхронным? - PullRequest
0 голосов
/ 28 июня 2018

Используя Python 3.6 и asyncio и aiohttp Я написал простую асинхронную программу:

from aiohttp import ClientSession
import asyncio, ssl, time

base_url = 'https://my-base-url.com/api'

async def fetch(session, id):
    query_params = {'qp1':'v1','qp2':'v2', 'id': id}
    async with session.get(base_url, params=query_params, ssl=ssl.SSLContext()) as response:
        res_json = await response.json()
        if response.status == 200:
            time.sleep(2)
            min_rating = res_json.get('minRating')
            max_rating = res_json.get('maxRating')
            print("id = %s, min = %s, max = %s" % (id, min_rating, max_rating))


async def run(ids):
    tasks = []
    async with ClientSession() as session:
        for id in ids:
            task = asyncio.ensure_future(fetch(session, id))
            tasks.append(task)

        responses = await asyncio.gather(*tasks)
        return responses


if __name__ == '__main__':
    ids = [123, 456, 789]
    future = asyncio.ensure_future(run(ids))
    event_loop = asyncio.get_event_loop()
    event_loop.run_until_complete(future)

    print("\n\ndone")

time.sleep(2) внутри fetch(session, id) создает впечатление, что эта программа не является асинхронной, потому что она получает один ответ, спит, получает другой, спит и так далее, и так далее. Когда я удаляю спящий вызов, он кажется асинхронным / параллельным, потому что ответы возвращаются в случайном порядке. Что sleep делает в этом случае? Это блокирует все темы? Почему он выглядит последовательным, а не параллельным?

1 Ответ

0 голосов
/ 28 июня 2018

time.sleep(2) является синхронным (блокирующим) вызовом, поэтому вы прекращаете асинхронный вызов с ним, вы должны использовать await asyncio.sleep(2), который будет «освобождать» ресурс.

...