как использовать Asynchttp в торнадо - PullRequest
0 голосов
/ 10 января 2019

AsynceHTTPClient не является неблокирующим клиентом?

когда я использую запросы для получения ответа, его работа. Но когда я использую AsyncTTTPClient для отправки запроса, он не работает.

async def go():
    print('go---------------')
    client = AsyncHTTPClient()
    request = HTTPRequest(url='http://127.0.0.1:8001/api', 
method='GET',)
    r = await client.fetch(request)
    print(r.code, r.body)

async def m(r):
    for _ in range(r):
        await go()

loop = asyncio.get_event_loop()
loop.run_until_complete(m(100))

когда я использую AsyncHTTPClient, я думаю, что результат похож на этот контент

иди --- иди --- иди --- иди --- ......

но реальный результат -

go --- 200 b '' go --- 200 b '' .......

Мне нужны неблокирующие запросы, поэтому он может сначала отправить все 100 запросов, а потом получить ответ, но я получил каждый ответ после каждого ответа. В этом режиме нет блокировки что-то не так с моим кодом? что мне делать?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

То, что вы видите, является недостатком использования сопрограмм в этом случае. Потому что, несмотря на то, что запросы не блокируют, они на самом деле не асинхронны

Вы можете использовать gen.WaitIterator для одновременной отправки всех запросов, действительно асинхронно.

Как сказано в документации:

Если вам нужно получить результат каждого будущего как можно скорее, или если вам нужен результат некоторых фьючерсов, даже если другие выдают ошибки, вы можете использовать WaitIterator.

Отлично подходит для вашего случая использования.

gen.WaitIterator принимает произвольное количество фьючерсов в качестве аргументов и возвращает фьючерсы по мере их завершения.

Однако, чтобы это работало, вам нужно переместить петлю for в сопрограмму go. Пример: * +1022 *

from tornado import gen

async def go(r):
    client = AsyncHTTPClient()
    futures = []

    for _ in range(r):
        print('go----------')
        request = HTTPRequest(url='http://127.0.0.1:8001/api', method='GET',)
        futures.append(client.fetch(request))

    async for result in gen.WaitIterator(*futures):
        print(result.code, result.body)

Как примечание, есть еще один способ сделать это - использовать обратные вызовы. Однако WaitIterator должно быть предпочтительнее обратных вызовов. Я написал сообщение в блоге об этом некоторое время назад, если вам интересно.

0 голосов
/ 10 января 2019

200 - ваш код состояния. Это идет как

go--- r.status_code b'' go--- r.status_code b'' .......

При удалении вашего кода состояния из печати должна быть печать

go--- go--- go--- go--- ......

...