So I have doubts what of 2 approaches to install AsyncIOMainLoop() I saw is more true. Which of them is more appropriate ?
1st When AsyncIOMainLoop() installed in make_app() code:
class MainHandler(tornado.web.RequestHandler):
async def get(self, *args, **kwargs):
return self.write("OK")
async def post(self, *args, **kwargs):
return self.write("OK")
def make_app():
tornado.platform.asyncio.AsyncIOMainLoop().install()
return tornado.web.Application([(r"/", MainHandler),],
debug=False)
def start_app():
app = make_app()
app.listen(8888)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
start_app()
2nd when AsyncIOMainLoop() installed in start_app() code:
class MainHandler(tornado.web.RequestHandler):
async def get(self, *args, **kwargs):
return self.write("OK")
async def post(self, *args, **kwargs):
return self.write("OK")
def make_app():
return tornado.web.Application([(r"/", MainHandler),],
debug=False)
def start_app():
tornado.platform.asyncio.AsyncIOMainLoop().install()
app = make_app()
app.listen(8888)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
start_app()
What do you think what of these 2 approaches is more appropriate ?
With 1st one I have troubles with running more than 2 tests in one AsyncHTTPTestCase suite with error like this:
Traceback (most recent call last):
File "/home/kamyanskiy/.local/share/virtualenvs/test-0zFWLpVX/lib/python3.6/site-packages/tornado/testing.py", line 380, in setUp
self._app = self.get_app()
File "/home/kamyanskiy/work/test/test_app.py", line 10, in get_app
return web1.make_app()
File "/home/kamyanskiy/work/test/web1.py", line 74, in make_app
tornado.platform.asyncio.AsyncIOMainLoop().install()
File "/home/kamyanskiy/.local/share/virtualenvs/test-0zFWLpVX/lib/python3.6/site-packages/tornado/ioloop.py", line 181, in install
assert not IOLoop.initialized()
AssertionError
With 2nd one, when AsyncIOMainLoop() is installed in start_app() code - tests are running ok, but here I have doubts that during tests AsyncIOMainLoop() is not used.
Tests looks like:
from tornado.testing import AsyncHTTPTestCase
import web1
class TestTornadoAppBase(AsyncHTTPTestCase):
def get_app(self):
return web1.make_app()
# I have to uncomment this for 1st code example
# def tearDown(self):
# self.io_loop.clear_instance()
# super().tearDown()
class TestGET(TestTornadoAppBase):
def test_root_get_method(self):
response = self.fetch("/")
self.assertEqual(response.code, 200)
self.assertEqual(response.body.decode(), 'OK')
def test_root_post_method(self):
response = self.fetch("/", method="POST", body='{"k": "v"}')
self.assertEqual(response.code, 200)
self.assertEqual(response.body.decode(), 'OK')
So what is true way to select where to init AsyncIOMainLoop() ?
Definitely the 2nd example as the documentation says:
from tornado.platform.asyncio import AsyncIOMainLoop
import asyncio
AsyncIOMainLoop().install()
asyncio.get_event_loop().run_forever()
The point is that AsyncIOMainLoop
has to be installed before you tell asyncio
to run the loop.