Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you understand the ioloop in tornado?

Tags:

python

tornado

I am looking for a way to understand ioloop in tornado, since I read the official doc several times, but can't understand it. Specifically, why it exists.

from tornado.concurrent import Future
from tornado.httpclient import AsyncHTTPClient
from tornado.ioloop import IOLoop
def async_fetch_future():
    http_client = AsyncHTTPClient()
    future = Future()
    fetch_future = http_client.fetch(
        "http://mock.kite.com/text")
    fetch_future.add_done_callback(
        lambda f: future.set_result(f.result()))
    return future

response = IOLoop.current().run_sync(async_fetch_future) 
# why get current IO of this thread? display IO, hard drive IO, or network IO? 
print response.body

I know what is IO, input and output, e.g. read a hard drive, display graph on the screen, get keyboard input. by definition, IOLoop.current() returns the current io loop of this thread.

There are many IO device on my laptop running this python code. Which IO does this IOLoop.current() return? I never heard of IO loop in javascript nodejs.

Furthermore, why do I care this low level thing if I just want to do a database query, read a file?

like image 992
Nicolas S.Xu Avatar asked Jul 20 '18 03:07

Nicolas S.Xu


People also ask

What is Tornado Ioloop?

In Tornado 6.0, IOLoop is a wrapper around the asyncio event loop, with a slightly different interface. The IOLoop interface is now provided primarily for backwards compatibility; new code should generally use the asyncio event loop interface directly.

How do you stop a tornado Ioloop?

To use asynchronous methods from otherwise-synchronous code (such as unit tests), you can start and stop the event loop like this: ioloop = IOLoop() async_method(ioloop=ioloop, callback=ioloop. stop) ioloop. start() ioloop.

How does tornado Python work?

Tornado is a Python web framework and asynchronous network library, originally developed at FriendFreed. Tornado uses non-blocking network-io. Due to this, it can handle thousands of active server connections. It is a saviour for applications where long polling and a large number of active connections are maintained.

What is Tornado module in Python?

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.


2 Answers

I never heard of IO loop in javascript nodejs.

In node.js, the equivalent concept is the event loop. The node event loop is mostly invisible because all programs use it - it's what's running in between your callbacks.

In Python, most programs don't use an event loop, so when you want one, you have to run it yourself. This can be a Tornado IOLoop, a Twisted Reactor, or an asyncio event loop (all of these are specific types of event loops).

Tornado's IOLoop is perhaps confusingly named - it doesn't do any IO directly. Instead, it coordinates all the different IO (mainly network IO) that may be happening in the program. It may help you to think of it as an "event loop" or "callback runner".

like image 197
Ben Darnell Avatar answered Sep 30 '22 23:09

Ben Darnell


Rather to say it is IOLoop, maybe EventLoop is clearer for you to understand.

IOLoop.current() doesn't really return an IO device but just a pure python event loop which is basically the same as asyncio.get_event_loop() or the underlying event loop in nodejs.

The reason why you need event loop to just do a database query is that you are using event-driven structure to do databse query(In your example, you are doing http request).

Most of time you do not need to care about this low level structure. Instead you just need to use async&await keywords.

Let's say there is a lib which supports asynchronous database access:

async def get_user(user_id):
    user = await async_cursor.execute("select * from user where user_id = %s" % user_id)
    return user

Then you just need to use this function in your handler:

class YourHandler(tornado.web.RequestHandler):

    async def get():
        user = await get_user(self.get_cookie("user_id"))
        if user is None:
            return self.finish("No such user")
        return self.finish("Your are %s" % user.user_name)
like image 31
Sraw Avatar answered Sep 30 '22 23:09

Sraw