2012-08-10 13 views
5

जो मैं समझता हूं उससे tornado.gen मॉड्यूल दस्तावेज़ों से यह है कि tornado.gen.Task में tornado.gen.Callback और tornado.gen शामिल हैं। अद्वितीय कॉल के साथ जुड़े प्रत्येक कॉलबैक/प्रतीक्षा जोड़ी के साथ प्रतीक्षा करें। ..टॉरनाडो असिंक HTTP रिटर्निंग परिणाम वृद्धिशील

@tornado.web.asynchronous 
    @tornado.gen.engine 
    def get(self): 
     http_client = AsyncHTTPClient() 
     http_client.fetch("http://google.com", 
         callback=(yield tornado.gen.Callback("google"))) 

     http_client.fetch("http://python.org", 
         callback=(yield tornado.gen.Callback("python"))) 

     http_client.fetch("http://tornadoweb.org", 
         callback=(yield tornado.gen.Callback("tornado"))) 
     response = yield [tornado.gen.Wait("google"), tornado.gen.Wait("tornado"), tornado.gen.Wait("python")] 

     do_something_with_response(response) 
     self.render("template.html") 

तो उपर्युक्त कोड विभिन्न यूआरएल से सभी प्रतिक्रिया प्राप्त करेगा। अब मुझे वास्तव में पूरा करने की आवश्यकता है जैसे ही एक http_client डेटा लौटाता है, प्रतिक्रिया को वापस करना है। तो अगर 'tornadoweb.org' पहले डेटा लौटाता है, तो उसे स्वयं लिखना चाहिए (लिखना) और def में एक लूप() को अन्य http_clients को पूरा करने के लिए इंतजार करना चाहिए। tornado.gen इंटरफ़ेस का उपयोग करके इसे लिखने के बारे में कोई भी विचार।

मैं क्या इस

class GenAsyncHandler2(tornado.web.RequestHandler): 
    @tornado.web.asynchronous 
    @tornado.gen.engine 
    def get(self): 
     http_client = AsyncHTTPClient() 
     http_client.fetch("http://google.com", 
          callback=(yield tornado.gen.Callback("google"))) 

     http_client.fetch("http://python.org", 
          callback=(yield tornado.gen.Callback("python"))) 

     http_client.fetch("http://tornadoweb.org", 
          callback=(yield tornado.gen.Callback("tornado"))) 

     while True: 
      response = self.get_response() 
      if response: 
       self.write(response) 
       self.flush() 
      else: 
       break 
     self.finish() 


    def get_response(self): 
     for key in tornado.gen.availableKeys(): 
      if key.is_ready: 
       value = tornado.gen.pop(key) 
       return value 
     return None 

उत्तर

3

इस के अलावा, वास्तव में नहीं है एक विधि WaitAll जो सभी परिणाम और रिटर्न के लिए इंतजार कर रहा है जब सभी HTTPCliens दे पूरा कर लिया है प्रतिक्रियाओं। मैंने अपनी टर्ननाडो शाखा में भिन्नता जमा की है (https://github.com/pranjal5215/tornado)। मैंने एक क्लास WaitAny जोड़ा है जो async WaitAll है और जैसे ही एक HTTP क्लाइंट परिणाम लौटाता है परिणाम देता है।

Diff, (https://github.com/pranjal5215/tornado/commit/dd6902147ab2c5cbf2b9c7ee9a35b4f89b40790e) में है (https://github.com/pranjal5215/tornado/wiki/Add-WaitAny-to-make-WaitAll-return-results-incrementally)

नमूना उपयोग:

class GenAsyncHandler2(tornado.web.RequestHandler): 
    @tornado.web.asynchronous 
    @tornado.gen.engine 
    def get(self): 
     http_client = AsyncHTTPClient() 
     http_client.fetch("http://google.com", 
          callback=(yield tornado.gen.Callback("google"))) 

     http_client.fetch("http://python.org", 
          callback=(yield tornado.gen.Callback("python"))) 

     http_client.fetch("http://tornadoweb.org", 
          callback=(yield tornado.gen.Callback("tornado"))) 
     keys = set(["google", "tornado", "python"]) 
     while keys: 
      key, response = yield tornado.gen.WaitAny(keys) 
      keys.remove(key) 
      # do something with response 
      self.write(str(key)+"  ") 
      self.flush() 
     self.finish() 
4

यह बात है तो आपको inline callbacks उपयोग नहीं करना चाहिए जब, यानी gen जैसा होगा करने के लिए कोशिश कर रहा हूँ की बहुत अस्पष्ट कार्यान्वयन (और वाक्य रचना गलत)। सभी कॉलबैक समाप्त होने के बाद self.render भी कॉल किया जाएगा। यदि आप आंशिक रूप से सर्वर से प्रतिक्रिया वापस करना चाहते हैं - इसे आंशिक रूप से प्रस्तुत करें।

सोचो इस तरह से (यह सुधार के बड़े कमरे के साथ ही विचार है):

response = [] 
    @tornado.web.asynchronous 
    def get(self): 
     self.render('head.html') 
     http_client = AsyncHTTPClient() 

     http_client.fetch("http://google.com", 
         callback=self.mywrite) 

     http_client.fetch("http://python.org", 
         callback=self.mywrite) 

     http_client.fetch("http://tornadoweb.org", 
         callback=self.mywrite) 

     self.render('footer.html') 
     self.finish() 


    def mywrite(self, result): 
     self.render('body_part.html') 
     self.response.add(result) 
     if len(self.response) == 3: 
     do_something_with_response(self.response) 
संबंधित मुद्दे