The request handlers are as follows:
class TestHandler(tornado.web.RequestHandler): # localhost:8888/test
@tornado.web.asynchronous
def get(self):
t = threading.Thread(target = self.newThread)
t.start()
def newThread(self):
print "new thread called, sleeping"
time.sleep(10)
self.write("Awake after 10 seconds!")
self.finish()
class IndexHandler(tornado.web.RequestHandler): # localhost:8888/
def get(self):
self.write("It is not blocked!")
self.finish()
When I GET localhost:8888/test
, the page loads 10 seconds and shows Awake after 10 seconds
; while it is loading, if I open localhost:8888/index
in a new browser tab, the new index page is not blocked and loaded instantly. These fit my expectation.
However, while the /test
is loading, if I open another /test
in a new browser tab, it is blocked. The second /test
only starts processing after the first has finished.
What mistakes have I made here?
Non-Blocking: It refers to the program that does not block the execution of further operations. Non-Blocking methods are executed asynchronously. Asynchronously means that the program may not necessarily execute line by line.
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
The reason is that Tornado is an asynchronous server with only one thread.
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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With