Understanding Tornado.gen

Source: Internet
Author: User

transferred from: http://blog.xiaogaozi.org/2012/09/21/understanding-tornado-dot-gen/Understanding Tornado.gen

SEP 21ST, 2012

Tornado @asynchronous uses decorator to implement asynchronous requests, but the request handler and callback must be separated when used, and the tornado.gen module can help us do both of these tasks in a function. Here is an example of the official:

12345678      
ClassGenasynchandler(RequestHandler): @asynchronous @gen. Engine Defget (self  Http_client = asynchttpclient ()  response = yield gen. Task (http_client. Fetch)   Do_something_with_response (response)  self. Render ( "template.html" )       

Here the two decorator are slightly more complex, the first one @asynchronous will be executed first, and its main work is to set RequestHandler the attribute to the _auto_finish false following:

Web.pydownload
123456789        
DefAsynchronous(Method): @functools. Wraps(Method) DefWrapper(Self,*Args,**Kwargs): IfSelf.Application._wsgi: RaiseException("@asynchronous is not supported for WSGI apps")  self. _auto_finish = false with  Stack_context. Exceptionstackcontext ( self. _stack_context_handle_exception):  return  Method (self*args **kwargs)   return wrapper             

Then there is the most important thing, which takes @gen.engine full advantage of the various features of generator, first of all to see @gen.engine the implementation (I have omitted some of the code to simplify understanding):

Gen.pydownload
123456789       
DefEngine(Func): @functools. Wraps(Func) DefWrapper(*Args,**Kwargs): gen = func (*args **kwargs)   If isinstance (gentypes generatortype):  runner = runner (gen)  runner run () return return wrapper            

local variable   Gen   represents   in the first paragraph of code, get   function, because   get   contains   yield   statement, so it becomes a generator. Notice here   get   is not executed, but is assigned to   Gen . The next step is to run   Runner   Object   run   function. In understanding   Run   need to know generator is by calling   next ()   or   send ()   To start, the boot will be encountered  , yield   Place hold, and then the   yield   return value of the subsequent statement is returned to the caller, Generator is in a paused state at this point, and all contexts will be saved. Call   again; next ()   or   send ()   will resume generator operation, if you no longer encounter   yield The   statement throws   stopiteration   exception. The return value is always the same as   while the yield   statement itself returns, if it is restored by calling   next ()  . None , and if it is through   send ()   The return value depends on the parameters passed to   send ()  . For more information on generator, please refer to the official documentation.

In combination with the first paragraph of the sample code, it can be thought that run the job is to start generator, then get the gen.Task object and call the function, and so on back to return after the return of the http_client.fetch generator run, and finally the callback returned value by send() assigning response . Here's my simplified code.

Gen.pydownload
123456789       
DefRun(Self): WhileTrue: IfNotSelf.Yield_point.Is_ready(): Return Next=Self.Yield_point.Get_result() Try: yielded=Selfgen. Send (next)  except stopiteration: return Span class= "K" >if isinstance (yielded yieldpoint):  self. Yield_point = yielded self.< span class= "n" >yield_point. Start (self)         

Line 3rd checks to see if the callback is complete and the first run run is always returned True . The 5th row gets the return value of the callback, and the same first run returns the None . will be None passed to send() start generator, yielded which is the gen.Task object, line 12th calls start to start running the function we really need to run, corresponding to the sample code is the http_client.fetch function, and as a Runner result_callback callback function 。 As follows:

Gen.pydownload
123456789       
DefResult_callback(Self,Key): DefInner(*Args,**Kwargs): IfKwargsOrLen(Args)>1: Result=Arguments(Args,kwargs)  elif args : result = args [0] else:< Span class= "line", result = none self. Results[key = result  self. Run ()  return inner      

Called again after the return value of the callback is obtained, run by get_result getting the return value, and then returning the return value to the response code flow that was assigned to continue request handler.

Understanding Tornado.gen

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.