Making websites with Tornado (7)

Source: Internet
Author: User

transferred from: http://wiki.jikexueyuan.com/project/start-learning-python/309.htmlMaking websites with Tornado (7)

To the end of the last section, in fact, the reader has been able to do a website, but only with the previous technology to do the site, only to calculate a small site, in the "Prepare for the site", the reason why choose Tornado, is because it can solve the c10k problem, that is, to achieve large user volume access.

To achieve large user-volume access, you have to do this: asynchronously. Unless you are a local tyrants of dirt.

Related Concepts synchronous and asynchronous

There is a lot of information to explain these two concepts at different angles and levels. In my opinion, one of the most typical examples is calling and texting.

    • The phone is synchronized. Zhang San to John Doe call, Zhang San said: "Is John Doe?" ”。 When this message is Zhang San sent to John Doe, it waits for John Doe response ("Yes", or "no"), and only after receiving the information returned by John Doe can the subsequent information be transmitted.
    • Texting is asynchronous. Zhang San to John Doe texting, edited a sentence "Tonight together to see the old Qi 0 basic Python", sent to John Doe. John Doe may reply immediately, perhaps after some time, this time how long also uncertain, only then reply. In short, Li four no matter when reply, Zhang San will hear text message ringtone as a hint to see the text message.

The above way of understanding "synchronization" and "async" is not very precise, some places or have forced. To be strictly understood, a strict definition is required (the following statements refer to the answers above):

Synchronous and asynchronous attention is to the message communication mechanism (synchronous communication/asynchronous communication)

The so-called synchronization is that when a "call" is issued, the "call" does not return until the result is obtained. But once the call returns, it gets the return value. In other words, the "caller" actively waits for the result of this "call".

Instead of async, the call returns immediately after the call is made, so no results are returned. In other words, when an asynchronous procedure call is made, the caller does not get the result immediately. Instead, after the call is issued, the callee notifies the caller by status, notification, or through a callback function to handle the call.

Maybe it's better to make a phone call and send a message earlier.

Blocking and non-blocking

"Blocking and non-blocking" and "synchronous and asynchronous" are often swapped for a talk, but there are still differences between them. If you follow a "almost" way of thinking, you can also not delve into the academic gap between them, anyway in your program, will be used. However, the necessary rigor or need, especially I write this tutorial, to dress up so that others seem to understand, so I quote the instructions (I personally think that others have done very good things, do not repeat the work, "Take doctrine", also good. Maybe you said I copied and cottage, but I specifically told you the source of it):

Blocking and non-blocking concerns the state of the program when it waits for the call result (message, return value).

A blocking call means that the current thread is suspended until the call results are returned. The calling thread will not return until the result is obtained. A non-blocking call means that the call does not block the current thread until the result is not immediately available.

According to this note, texting is obviously non-blocking, sent to a text message, you can use the mobile phone to do other, and even send a "old Qi course boring, or see PHP stimulation" is also possible.

The analysis of these two sets of basic concepts is not the focus of this tutorial, readers can refer to this article: Http://www.cppblog.com/converse/archive/2009/05/13/82879.html, the author of the article made a nuanced analysis.

Synchronization of Tornado

Previously, on the basis of tornado has been completed on the web, is synchronous, blocking. In order to feel this more clearly, you might as well give it a try.

Create a file in the Handlers folder named sleep.py

#!/usr/bin/env python# coding=utf-8from base import Basehandlerimport timeclass sleephandler (Basehandler): def get (self): Time.sleep ( 17) self.render ( "sleep.html") class seehandler (BaseHandler): def get ( Self): Self.render ( "see.html")        

Other things, if the reader to me in the "Use Tornado website (1)" described in the website framework familiar, should know how to do, unfamiliar, please go back to review.

Sleep.html and see.html are two simple templates that can be written on their own. Don't forget to modify the directory in url.py.

Then the test is a little more complicated, that is, after opening the browser, open two tags, respectively, in two tags localhost:8000/sleep (labeled 1) and (labeled as Tag localhost:8000/see 2), note that I use 8000 port. Please do not click Enter to access. Be prepared to remember that toggle tags can be combined with the "Ctrl-tab" key.

    1. Execute the label 1 and let it visit the website;
    2. Switch to label 2 now to access the URL.
    3. Note that the two tab pages are not all in the show being accessed, please wait.
    4. How does label 2 behave when label 1 does not render a wait prompt (such as a circle that is being turned)? Almost at the same time also the visit succeeded.

It is recommended that the reader modify the value of Time.sleep (17) in sleep.py and try more. It's fun.

Of course, this is a rather clumsy method, which could have been compared by testing the tool to do the above. Zennai to use other tools, but also to introduce, but also a more decentralized things, so clumsy way, right when there is an experience.

Asynchronous settings

Tornado is an asynchronous service framework that manifests itself in the asynchronous interaction between the Tornado server and the client, Tornado.ioloop.IOLoop. However, if the client requests the server, when executing a method, such as the above code in the execution of the Get () method, encountered time.sleep(17) this need to take a long time, time-consuming, will make the performance of the entire Tornado server is limited.

To solve this problem, Tornado provides a set of asynchronous mechanisms that are asynchronous adorners @tornado.web.asynchronous :

#!/usr/bin/env Python# coding=utf-8import tornado.web from base import basehandler Import Timeclass SleepHandler @tornado. web.asynchronous def get 17, Callback=self.on_response) def on_response  "sleep.html") self.finish ()   

The sleep.py code is modified as described above, i.e. the adorner is added before the Get () method @tornado.web.asynchronous , and its function is to modify the default setting value of the Tornado server itself _auto_fininsh to False. If you do not use this adorner, the client accesses the server's Get () method and gets the return value, the connection between the two is broken, but after it is used @tornado.web.asynchronous , the connection is not closed until it is executed to self.finish() close the connection.

tornado.ioloop.IOLoop.instance().add_timeout()is also an implementation of the asynchronous function, time.time()+17 is to provide a parameter to the preceding function, which implements the equivalent time.sleep(17) of the function, however, has not completed, when the operation is completed, the execution of the callback function on_response() self.render("sleep.html") , and close the connection self.finish() .

The process is clear. The so-called asynchronous, is to solve the original time.sleep(17) caused by the server processing time long, performance degradation problem. Workaround as described above.

Readers look at this code, perhaps feeling a little uncomfortable. If there is such a feeling, it is normal. Because it has a callback function in addition to the adorner, it allows the logic of the code not to be tiled, but to be divided into two segments. The first paragraph is tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 17, callback=self.on_response) that callback=self.on_response using the callback function is not as straightforward as before, and the self.render("sleep.html") second paragraph is the callback function on_response (self) ,要在这个函数里面执行 self.render ("sleep.html") ,并且以 Self.finish () ' ends to close the connection.

This is still the implementation of simple logic, if complex, and constantly to "callback", can not allow the logic to continue smoothly, the face will be "dizzy." This phenomenon is a "code logic split" by the industry, breaking the order of the original logic. In order for the code logic to be pieces, there is another common approach:

#!/usr/bin/env Python# coding=utf-8import tornado.web import tornado.genfrom base  Import Basehandlerimport time Class sleephandler (Tornado.web.RequestHandler):  @tornado. Gen.coroutine def getyield tornado.gen.Task ( Tornado.ioloop.IOLoop.instance (). Add_timeout, Time.time () + 17)  #yield tornado.gen.sleep Self.render ( "sleep.html")  

On the whole, this code avoids the callback function and looks much smoother.

Look at the detail section again.

The first thing to use is the @tornado.gen.coroutine adorner, so you have it in front import tornado.gen . Similar to this adorner is the @tornado.gen.engine adorner, which is similar in function, with a slight difference. Please read the official explanation for this:

This decorator (referring engine) is similar to coroutine, except it does no return a future and the callback argument are not Trea Ted specially.

@tornado.gen.engineIt was used in ancient times, and now we are all using it @tornado.gen.corroutine , which begins after Tornado 3.0. When you look at the information on the Internet, you will encounter some use @tornado.gen.engine , but when you use or reference the code, it is brave to modify it as @tornado.gen.coroutine well. With this adorner, you can control the flow of the generator below.

Then you see the yield in the Get () method, which is a generator (see the "Builder" in this tutorial). yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 17)the execution of the procedure, you should look at the parentheses, the same as the previous, is to replace time.sleep(17) , and then the tornado.gen.Task() method, its role is "adapts a callback-based asynchronous function for use in Corout Ines. " (for fear of missing information after translation, refer to the original text). After returning, finally using yield to get a generator, the process is suspended, and so on, and then wake up to continue execution. To remind the reader that the generator is asynchronous.

In fact, the above long-winded pair, you can use the code in the comments of a sentence to replace yield tornado.gen.sleep(17) , the reason for expansion, is to see the tornado.gen.Task() way, because if the reader in the old code, will encounter. But, after you write, don't be so wordy, please use yield tornado.gen.sleep() .

At this point, there is basically an overview of the asynchronous setup of Tornado, but the above program is of little value in practice. In the project, to make the Tornado website really asynchronous, but also to do a lot of things, not just as the above settings, because a lot of things, in fact, are not asynchronous.

In practice, asynchronous

The following items are synchronized (blocked), and if they are used only in tornado, the non-blocking, asynchronous advantages of the tornado are reduced.

    • All operations of the database, whether your data is SQL or nosql,connect, insert, UPDATE, etc.
    • File operations, opening, reading, writing, etc.
    • Time.sleep, as already seen in the example above
    • Smtplib, e-mail operation
    • Some network operations, such as Tornado's httpclient and Pycurl

In addition to the above, perhaps in the programming practice will encounter other synchronization, blocking practice. Just a few of the above, is the programming practice often encountered, how to solve?

The clever Daniel programmer helped us with the expansion module, which was designed to implement asynchronous/non-blocking.

    • In the database, because of a wide variety, can not be explained, such as MySQL, the use of the ADB module to implement the Python asynchronous MySQL library, for the MongoDB database, there is a very good module dedicated to Tornado and MONGODB implementation of asynchronous operations, it is motor. Special stickers out its logo, I like. Official website: http://motor.readthedocs.org/en/stable/on the installation and use of the method are very detailed.

    • There is no replacement module for file operations, only try to control the IO as much as possible, or use a memory-based (Redis) and document-type (MongoDB) database.
    • Time.sleep () has an alternative in tornado: tornado.gen.sleep() or tornado.ioloop.IOLoop.instance().add_timeout , this is already shown in the previous code.
    • SMTP sends a message and recommends change to tornado-smtp-client.
    • For network operations, use Tornado.httpclient.AsyncHTTPClient.

Other solutions can only see that the problem is specific, and there is not even a good solution. However, there is a list of enough libraries for the user to choose: Async Client Libraries built on Tornado.ioloop, and there are many other links on this page, all of which are good resources and suggest a lot of reading.

Tutorial here, the reader is not to think of a problem, since there is a dedicated motor library for MongoDB to achieve asynchrony, the front for tornado async, no matter which decorator, all feel trouble, there is no dedicated library to achieve this kind of asynchronous? It's not whimsical, it really is. Also should have, because this only embodies the characteristics of Python. such as Greenlet-tornado, is a good library. Readers can browse the official website for more information (why not be positive about MySQL?). Supposedly should come out a lot of support MySQL asynchronous Coucay pair).

It must be stated that the previous demonstration of how to set the async code in Tornado is simply a demonstration of understanding the Setup method. In engineering practice, the meaning of that code is not. To do this, there should be a code example that approximates the practice. Yes, there should be. When I was about to write this code, I found an article on the internet that prevented me from writing because the author of the article I was writing was already written, and I thought the presentation was very good and the examples were detailed. So, I had to give up and recommend this good article to the reader instead:

Example: http://emptysqua.re/blog/refactoring-tornado-coroutines/

Making websites with Tornado (7)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.