Tornado 4.0 has been released for a long time, and the new version has a wide range of application of the co-process (future) feature. We have now upgraded the Tornado to the latest version, and we have also used a lot of the co-process features.
A long time did not update the blog, today is a brief introduction of the implementation of the principle of Tornado, the Tornado is based on the Python generator implementation, so first to review the generator.
Generator
The Python Builder can save the execution state and restore it at the next call by using the yield keyword in the function body to create a generator that restores the generator's state through the built-in function next or the next method of the generator.
def test (): yield 1
We call the test function, which does not return a result, but instead returns a generator
>>> Test ()
We call its next method to return the content after the yield keyword.
>>> t = Test () >>> T.next () 1
If we then call the next method, and no yield keyword continues to return, a Stopiteration exception will be thrown.
The yield keyword not only returns the state from within the generator, but it can also pass external information inside the generator by assigning the Yeild key to the variable and invoking the generator's send method to pass the object inside the generator. It is important to note that the start of the generator must call its next method, and the subsequent send method call will also trigger the next action. If no variable receives the yield keyword then the value sent by send will be discarded.
>>> def Test (): a = yield print (a)
First call next the generator returned by the above function will return none, if this time directly call next will send to the generator none, if the call to send a value, will print this value and throw stopiteration exception.
A simple way to co-process
The above is all the basis of the implementation of the process, in order to deepen understanding, we write a small example here, example we only use the process to open two or more dead loops, here is an extremely simple example:
#!/usr/bin/env python#-*-coding:utf-8-*-
From __future__ import Absolute_import, print_function, Division, With_statementdef LOOP1 (): "" " Loop 1 is responsible for throwing a function and corresponding parameters and receives the result "" " a = 0 ret = 1 while True: ret = yield sum, [A, ret] A, ret = ret, a print (" Loop1 RET ", ret)
Def loop2 (): "" " Loop 2 is responsible for receiving the function and calculating the result, then yields the result" "" while True: func, args = yield yield func (args)
print ("Loop2") L1 = Loop1 () L2 = LOOP2 () tmp = L1.next () for I in range: l2.next () ret = l2.send (TMP) TMP = L1.send (ret)
In the example above, LOOP1 is responsible for generating the task, LOOP2 is responsible for performing the task, and the main loop is responsible for dispatching the task and sending the result back to the task creator.
Tornado how to do that
Let's start by looking at an example of asynchronous using Tornado
#!/usr/bin/env python#-*-coding:utf-8-*-from __future__ import absolute_import, print_function, Division, With_ Statementfrom Tornado import genfrom Tornado import webfrom Tornado import Httpclientclass actionhandler (web. RequestHandler): @gen. Coroutine def get (self): response = yield httpclient. Asynchttpclient (). Fetch ("http://www.linuxzen.com") # ...
In fact, the principle in the above simple example has been made clear, we can briefly analyze the above example, first Tornado get the Actionhandler.get method throws (next) a task, and then asynchronously to perform the task, when the Task (network request) end or an exception Tornado gets the event notification and then puts the result back (send) into the method so that the method continues execution.
Because it is asynchronous, calling this method does not block other tasks from executing.
At this point our approach is actually the last example of the LOOP1 function, and Tornado dispatches and executes the task it throws.
Summarize
Tornado asynchronous can make asynchronous appear to be executed sequentially and can be freed from a large string of callback.
Tornado asynchronous is not the few words can be said clearly, which has a very complex packaging and transmission, interested in reading the source itself.