Python tornado RequestHandler 中的 AsyncHttpClient 抛出异常
Python AsyncHttpClient inside tornado RequestHandler throws exception
我打算在 RequestHandler 中通过 tornado AsyncHttpClient 调用端点,但它抛出运行时异常 This event loop is already running
class RegistrationHandler(tornado.web.RequestHandler):
def post(self, *args, **kwargs):
call_async_register("some params")
def call_async_register(parameters):
def call():
http_client = AsyncHTTPClient()
future = Future()
http_request = HTTPRequest(url, request_type.name, headers={'X-Peering': '1'}, body=body)
def handle_future(f: Future):
future.set_result(f.result())
fetched_future = http_client.fetch(http_request)
fetched_future.add_done_callback(handle_future)
return future
try:
instance = io_loop.IOLoop.current()
response = instance.run_sync(call)
return response.body.decode()
except Exception as err:
self.logger.exception("Account Request Failed: {}".format(err))
return None
这是问题所在:
instance = io_loop.IOLoop.current()
response = instance.run_sync(call)
run_sync
本身尝试启动 ioloop。但是从您的代码可以看出,instance
已经是 运行。所以你得到了错误。
如果您想将 call()
方法返回的值发送回用户,请将您的方法转换为协程(使用 async/await
语法)。
示例:
class RegistrationHandler(tornado.web.RequestHandler):
async def post(self, *args, **kwargs):
response = await call_async_register("some params")
self.write(response)
async def call_async_register(parameters):
http_client = AsyncHTTPClient()
http_request = HTTPRequest(url, request_type.name, headers={'X-Peering': '1'}, body=body)
try:
response = await http_client.fetch(http_request)
return response.body.decode()
except Exception as err:
self.logger.exception("Account Request Failed: {}".format(err))
return None
我打算在 RequestHandler 中通过 tornado AsyncHttpClient 调用端点,但它抛出运行时异常 This event loop is already running
class RegistrationHandler(tornado.web.RequestHandler):
def post(self, *args, **kwargs):
call_async_register("some params")
def call_async_register(parameters):
def call():
http_client = AsyncHTTPClient()
future = Future()
http_request = HTTPRequest(url, request_type.name, headers={'X-Peering': '1'}, body=body)
def handle_future(f: Future):
future.set_result(f.result())
fetched_future = http_client.fetch(http_request)
fetched_future.add_done_callback(handle_future)
return future
try:
instance = io_loop.IOLoop.current()
response = instance.run_sync(call)
return response.body.decode()
except Exception as err:
self.logger.exception("Account Request Failed: {}".format(err))
return None
这是问题所在:
instance = io_loop.IOLoop.current()
response = instance.run_sync(call)
run_sync
本身尝试启动 ioloop。但是从您的代码可以看出,instance
已经是 运行。所以你得到了错误。
如果您想将 call()
方法返回的值发送回用户,请将您的方法转换为协程(使用 async/await
语法)。
示例:
class RegistrationHandler(tornado.web.RequestHandler):
async def post(self, *args, **kwargs):
response = await call_async_register("some params")
self.write(response)
async def call_async_register(parameters):
http_client = AsyncHTTPClient()
http_request = HTTPRequest(url, request_type.name, headers={'X-Peering': '1'}, body=body)
try:
response = await http_client.fetch(http_request)
return response.body.decode()
except Exception as err:
self.logger.exception("Account Request Failed: {}".format(err))
return None