2

I am aware that since 5.0 tornado's ioloop is handled by asyncio and in fact the loop I get using tornado.ioloop.IOloop.current() is an asyncio loop by default. My question is how do I access the asyncio loop itself in a proper way. For example I would like to use the loop.create_future() method on the asyncio loop, but tornado wraps the loop and it doesn't have this method on it.

Currently what I do is when I need asyncio methods I just call asyncio.get_event_loop() (because the documentation states that the two loops are indeed identical). I am not sure this is the correct way of doing this since now I have different references to the same ioloop with different interfaces and I use the one that is needed. This is kind of messy and confusing.

Is there a better way? Can I tell tornado to give me the asyncio loop without wrapping it? Or can I access these methods somehow using the IOloop that tornado creates?

EDIT:

https://www.tornadoweb.org/en/stable/ioloop.html#module-tornado.ioloop Here it states the following:

Applications can use either the IOLoop interface or the underlying asyncio event loop directly

I am interested in the latter, yet I can’t find instructions on how to access it directly.

MrBlaise
  • 970
  • 7
  • 21
  • Have you tried asyncio's top-level functions, such as ``asyncio.ensure_future``? The event loop is generally published for its payloads. – MisterMiyagi Dec 04 '19 at 07:27
  • In the specific use case I mentioned (but I'd rather ask this generally) I had to create a asyncio.Future object and asyncio's documentation clearly states that to do that properly you need to call `create_future()` on the loop. https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.create_future Am I missing something, is there a top level method for everything to be used in tornado? – MrBlaise Dec 04 '19 at 07:33

2 Answers2

2

asyncio.get_event_loop() is the recommended method; no need to use the (undocumented) asyncio_loop attribute. This is how all non-tornado-specific asyncio code gets the event loop.

Ben Darnell
  • 21,844
  • 3
  • 29
  • 50
  • Thanks for your answer! So if I already use tornado's ioloop's for calling add_callback and such things, is it considered a good practice to get the reference to the asyncio_loop via `asyncio.get_event_loop()` if I want to use methods that don't exists on tornado's ioloop, such as `create_future`? Or should I just use asyncio everywhere? – MrBlaise Dec 05 '19 at 08:39
  • I'd say it's a good practice to avoid mixing the two event loops in the same block of code, if possible. If you've already got an asyncio loop for `create_future`, use its `call_soon` instead of `add_callback`. But if you do need unique features of both loops, just use `IOLoop.current()` and `asyncio.get_event_loop()`. – Ben Darnell Dec 06 '19 at 13:50
0

I finally found a way. So the ioloop that tornado creates will be of type AsyncIOMainLoop. I went to the source code and its base class is BaseAsyncIOLoop in that class there is a property called asyncio_loop

With that I was finally able to use asyncio loop. (ioloop.IOLoop.current().asyncio_loop)

MrBlaise
  • 970
  • 7
  • 21