Торнадо не дает фьючерсы правильно - PullRequest
0 голосов
/ 31 января 2019

Мне нужно асинхронно выполнить несколько http-вызовов внутри обработчика запросов торнадо.

Попытка возврата фьючерсов плохо документирована и практически невозможно выполнить на собранном asyncio.gather на уровне обработчика торнадо.

Я попробовал aiohttp, который прекрасно работает сам по себе, однако, когда он помещается в обработчик торнадо, он запускает цикл, который уже используется.Если вы можете показать мне, как внедрить в IOLoop несколько новых фьючерсов для разрешения, это было бы неплохо.

Я также попытался использовать торнадо AsyncHTTPClient, который вопреки документации на самом деле не использует yield, но возвращаетответ, когда вы используете await на нем.

Есть ли актуальная документация по этому вопросу?ВСЕ пример не работает для нескольких асинхронных запросов.

в соответствии с этой документацией http://www.tornadoweb.org/en/stable/gen.html#module-tornado.gen

@gen.coroutine
def get(self):
    http_client = AsyncHTTPClient()
     response1, response2 = yield [http_client.fetch(url1),
                              http_client.fetch(url2)]
    response_dict = yield dict(response3=http_client.fetch(url3),
                           response4=http_client.fetch(url4))
    response3 = response_dict['response3']
    response4 = response_dict['response4']

, однако, при попытке сделать это самостоятельно, yield выдает ошибку, заменяя ее на await getрезультат.однако вы не можете ожидать такого объекта, как yield.Как я могу обойти это?

python 3.6.7 торнадо 5.1.1 aiohttp 3.5.4

1 Ответ

0 голосов
/ 02 февраля 2019

В ваших комментариях используется слово await, поэтому звучит так, будто вы сталкиваетесь с разницей между нативными сопрограммами (определенными с помощью async def и await) и декорированными сопрограммами (определенными с помощью @gen.coroutine и * 1005).*).Вы можете только yield списки и словари непосредственно в украшенных сопрограмм.

В нативной сопрограмме вы должны использовать tornado.gen.multi (или asyncio.gather):

async def get(self):
    http_client = AsyncHTTPClient()
    response1, response2 = await gen.multi([http_client.fetch(url1),
                                            http_client.fetch(url2)])
    response_dict = await gen.multi(dict(response3=http_client.fetch(url3),
                                         response4=http_client.fetch(url4)))
    response3 = response_dict['response3']
    response4 = response_dict['response4']

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

...