tornado
has its own event loop which is incompatible with asyncio
's event loop. But it can be solved.
First, create a BaseHandler
extended from tornado.web.RequestHandler
:
class BaseHandler(tornado.web.RequestHandler):
@staticmethod
def asyncio_task(method):
@functools.wraps(method)
async def wrapper(self, *args, **kwargs):
tornado_task = method(self, *args, **kwargs)
return await asyncio.ensure_future(tornado_task)
return wrapper
Second, decorate every http functions such as get
or post
with this decorator.
class MainHandler(BaseHandler):
@BaseHandler.asyncio_task
async def get(self):
return self.render("index.html")
Finally, run tornado
server in this way.
import asyncio
from server import make_app
from tornado.platform.asyncio import AsyncIOMainLoop
if __name__ == '__main__':
AsyncIOMainLoop().install()
app = make_app()
app.listen(options.port)
asyncio.get_event_loop().run_forever()