Python Tornado – A non-blocking web server
If a server is non-blocking, it means that the process can handle more than one requests at the same time and the request doesn’t have to wait for any I/O or other event to occur.
Traditional web server were synchronous and assigned each thread per user which were very costly, hence a single-threaded event loop can be used by Tornado to make the the code non-blocking and asynchronous as a single operation can be active at one time.
Tornado’s ioloop is the wrapper of asyncio.
Advantages of using non-blocking web server
- Easy to scale for large number of connections.
- More appropriate for real time systems where lot of background execution is required.
- Client doesn’t have to wait for the handler to complete its execution to get response.
Following are the useful decorators related to asynchronous execution.
If the function returns before its execution is finished and performs some background execution, then the function is asynchronous. In that case, the function can be decorated with asynchronous decorator.
This decorator is used when the callback approach is used for asynchronization.
Method must be executing something asynchronous in order to make the decorator meaningful.
When the decorator is used and if the request is not completed when the handler returns, we need to explicitly call self.finish() in order to complete the request.
import tornado class Handler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): http_client = httpclient.AsyncHTTPClient() http.fetch("https://www.google.co.in/search?q=python", callback=self.on_callback) def on_callback(self, response): self.write("In callback method") self.finish()
Note: Adding the generator will not make the function asynchronous, but it tells the framework about the same.
Recommended way to write asynchronous code in Tornado is by using coroutines. Instead of using chains of callbacks, it uses Python yield to resume and suspend the execution.
Have a look at the following example:
from tornado import gen @gen.coroutine def fetch_image(img_url): http_client = AsyncHTTPClient() response = yield http_client.fetch(img_url) return response.body
async and await keywords
Introduced from Python 3.5 and compatible from Tornado 4.3. Async and await can be used in places of yield based coroutines.
In addition to the decorator, @gen.coroutine can be replaced with the function definition as async def function_name() and yield can be replaced with await.
async def fetch_image(img_url): http_client = AsyncHTTPClient() response = await http_client.fetch(img_url) return response.body
That’s it. Hope you find it useful, thanks!
About CauseCode: We are a technology company specializing in Healthtech related Web and Mobile application development. We collaborate with passionate companies looking to change health and wellness tech for good. If you are a startup, enterprise or generally interested in digital health, we would love to hear from you! Let's connect at firstname.lastname@example.org