Search code examples
pythontornadononblocking

Confusion about Python Tornado's blocking


So I understand the basic idea that Tornado is itself non blocking with an event loop I/O, but that blocking IO operations like database access will result in Tornado blocking during those operations.

What I don't understand is why it seems that Tornado is blocking during non-blocking operations.

I have the following code in a handler:

class MyHandler(BaseHandler):

    def get(self):
        x = 0
        for i in xrange(0,500000000):
            x = i

        self.render("page_temp.html",
                    title="Page"
                    )

This takes ~20 seconds to load the page. If I open another browser window and try to load any other page, I get hung until the 20 second page loads. Could it be because both requests are from the same user?


Solution

  • You're doing a long, CPU-bound operation directly inside your handler. tornado is single-threaded, which means it can't do CPU-bound work in the event loop thread without blocking all your other requests. If you need to do CPU-bound work, you have to do it in a background thread or process.

    In order to make this method handle requests concurrently, it would need to look like this:

    from concurrent.futures import ThreadPoolExecutor
    from tornado import gen
    from tornado.web import RequestHandler
    
    executor = ThreadPoolExecutor(8) # 8 Threads in the pool
    
    class ThreadPoolHandler(RequestHandler):
    
        def _do_loop(self):
            x = 0
            for i in xrange(0,500000000):
                x = i
    
        @gen.coroutine
        def get(self):
            yield executor.submit(self._do_loop) # Run through the loop without blocking tornado
            self.render("page_temp.html",
                        title="Page"
                        )
    

    By using a ThreadPoolExecutor to run the expensive for-loop in a background thread, tornado can continue to serve other requests while waiting for the CPU work to complete.