I am trying to understand the basic example provided on the introduction page of tornado documentation. It has 2 blocks of code. The Synchronous one is fine for me, and I do understand it. But the asynchronous one is one I am not able to understand.
Synchronous
from tornado.httpclient import HTTPClient
def synchronous_fetch(url):
http_client = HTTPClient()
response = http_client.fetch(url)
return response.body
Asynchronous
from tornado.httpclient import AsyncHTTPClient
def asynchronous_fetch(url, callback):
http_client = AsyncHTTPClient()
def handle_response(response):
callback(response.body)
http_client.fetch(url, callback=handle_response)
If you can provide with a better example, please do so.
The idea of asynchronous calls is something that works pretty much the same in many web related programming... "stuff" (frameworks, servers, libraries...) Is not only a concept from the Tornado web server.
The basic idea is:
On a̲s̲y̲n̲c̲h̲r̲o̲n̲o̲u̲s̲ requests, you "launch" the request, and you kind of "forget about it", meaning: The interpreter continues executing the code after the request is made without waiting for the request to be completed.
This seems... rather pointless, right? You send the request "to the void of space", and continue executing as usual? What happens when the server sends you its response? I made a request, and I wanna know what happened to it! Otherwise, I wouldn't have typed that in my code to begin with!!
Well, here's where the
callback
comes in. You launch the request "to the void of space" BUT you provide a callback function so when the HTTP server on the other end sends you its response, that function is run with saidresponse
as the first argument.Let's see it with a en example.
I've created a very simple Tornado server (using
Python 2.7
andTornado 4.2
) with only one handler. On aGET
, it takes 5 seconds to return. I've done that with a time.sleep, but in real life, it could be a very time consuming process (access a database, perform some calculations... who knows?...)Here's the server file (based on the example provided in the Tornado documentation):
SampleServer.py
:Open a terminal and run that code to have a server. You'll get a Tornado listening on port
8888
of your local machine.Now, let's create another script (which you'll have to run in another terminal) that
GET
shttp://localhost:8888
in two ways: First synchronously and then asynchronously.SampleFetcher.py
:This will output:
Let's focus on the asynchronous part, here:
If you see, the script made the
asynchronous_fetch
at13:25:52
, but immediately (in the same second), the interpreter continued executing, and run the next statements after the request was made (the lines that printYou're gonna see this line before the "Yawwza..." one
andThis one too. Now is 2015/07/04 13:25:52
).Then, around 5 seconds later, the server responded, and the
callback
function (which washandle_response
) was executed, and that's when you seeI hope this helped understanding the idea a bit. It's a very useful concept, and it doesn't only apply to Tornado.
Feel free to play with the two sample scripts provided, change stuff, increase the times it gets for the server to reply...
Further recommended reading:
Futures