Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Синхронная выборка в Tornado

Автор вопроса: Laika_BossОтветов: 1

В официальной документации Tornado (https://www.tornadoweb.org/en/stable/guide/async.html) есть пример синхронной выборки, но когда я помещаю его в метод get моего IndexHandler, он возвращает следующую ошибку:

  File "/home/stefan/.local/lib/python3.6/site-packages/tornado/web.py", line 1697, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "ex1.py", line 19, in get
    client = tornado.httpclient.HTTPClient()
  File "/home/stefan/.local/lib/python3.6/site-packages/tornado/httpclient.py", line 107, in __init__
    self._async_client = self._io_loop.run_sync(make_client)
  File "/home/stefan/.local/lib/python3.6/site-packages/tornado/ioloop.py", line 526, in run_sync
    self.start()
  File "/home/stefan/.local/lib/python3.6/site-packages/tornado/platform/asyncio.py", line 148, in start
    self.asyncio_loop.run_forever()
  File "/usr/lib/python3.6/asyncio/base_events.py", line 428, in run_forever
    'Cannot run the event loop while another loop is running')
RuntimeError: Cannot run the event loop while another loop is running

Мой код выглядит так:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.options import define, options

define("port", default=8000, help="run on the given port", type=int)

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        client = tornado.httpclient.HTTPClient()
        response = client.fetch('https://www.google.com')
        print(response.body)


if __name__ == "__main__":
    tornado.options.parse_command_line()
    app=tornado.web.Application(handlers=[(r"/", IndexHandler)],debug=True)
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

Я считаю, что мне следует внести изменения в main, чтобы заставить его работать.

pythonsynchronoustornado

Ответы

Ответ 1 · Fine

Потому что, как вы можете видеть в вашей трассировке, "синхронный" fetch запускает свой собственный ioloop под капотом. Проще всего исправить def get как сопрограмму (либо как async def get, либо с помощью декоратора @gen.coroutine) и использовать асинхронную выборку.

class IndexHandler(tornado.web.RequestHandler):
    async def get(self):
        client = tornado.httpclient.HTTPClient()
        response = await client.fetch('https://www.google.com')
        print(response.body)

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы