Python Tornado - Asynchronous Request is blocking

后端 未结 2 1258
隐瞒了意图╮
隐瞒了意图╮ 2020-12-15 13:02

The request handlers are as follows:

class TestHandler(tornado.web.RequestHandler):    #  localhost:8888/test
    @tornado.web.asynchronous
    def get(self)         


        
相关标签:
2条回答
  • 2020-12-15 13:20

    What you are seeing is actually a browser limitation, not an issue with your code. I added some extra logging to your TestHandler to make this clear:

    class TestHandler(tornado.web.RequestHandler):    #  localhost:8888/test
        @tornado.web.asynchronous
        def get(self):
            print "Thread starting %s" % time.time()
            t = threading.Thread(target = self.newThread)
            t.start()
    
        def newThread(self):
            print "new thread called, sleeping %s" % time.time()
            time.sleep(10)
            self.write("Awake after 10 seconds!" % time.time())
            self.finish()
    

    If I open two curl sessions to localhost/test simultaneously, I get this on the server side:

    Thread starting 1402236952.17
    new thread called, sleeping 1402236952.17
    Thread starting 1402236953.21
    new thread called, sleeping 1402236953.21
    

    And this on the client side:

    Awake after 10 seconds! 1402236962.18
    Awake after 10 seconds! 1402236963.22
    

    Which is exactly what you expect. However in Chromium, I get the same behavior as you. I think that Chromium (perhaps all browsers) will only allow one connection at a time to be opened to the same URL. I confirmed this by making IndexHandler run the same code as TestHandler, except with slightly different log messages. Here's the output when opening two browser windows, one to /test, and one to /index:

    index Thread starting 1402237590.03
    index new thread called, sleeping 1402237590.03
    Thread starting 1402237592.19
    new thread called, sleeping 1402237592.19
    

    As you can see both ran concurrently without issue.

    0 讨论(0)
  • 2020-12-15 13:25

    I think you picked the "wrong" test for checking parallel GET requests, that's because you're using a blocking function for your test: time.sleep(), which its behavior doesn't really occur when you simply render an HTML page ...

    What happens is, that the def get() ( which handle all GET requests ) is actually being blocked when you use time.sleep it cannot process any new GET requests, puts them in some kind of "queue".

    So if you really want to test sleep() - use the Tornado non-blocking function: tornado.gen.sleep()

    Example:

    from tornado import gen
    
    @gen.coroutine
    def get(self):        
        yield self.time_wait()       
    
    @gen.coroutine
    def time_wait(self):
        yield gen.sleep(15)
        self.write("done")
    

    Open multiple tabs in your browser, then you'll see that all requests are being processed when they arrive w/o "queueing" the new requests that comes in ..

    0 讨论(0)
提交回复
热议问题