2012-08-10 33 views
5

Từ những gì tôi hiểu từ tài liệu mô-đun lốc xoáy. Đó là tornado.gen.Task bao gồm tornado.gen.Callback và tornado.gen.Wait với mỗi cặp Callback/Wait được kết hợp với các khóa duy nhất. ..Tornado Async HTTP trả về kết quả gia tăng

@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") 

Vì vậy, mã ở trên sẽ nhận được tất cả phản hồi từ các URL khác nhau. Bây giờ những gì tôi thực sự cần thực hiện là trả lại phản hồi ngay khi một http_client trả về dữ liệu. Vì vậy, nếu 'tornadoweb.org' trả về dữ liệu đầu tiên, nó phải làm một self.write (respose) và một vòng lặp trong def get() nên tiếp tục đợi các http_clients khác hoàn thành. Bất kỳ ý tưởng nào về cách viết điều này bằng giao diện tornado.gen.

thực hiện Rất mơ hồ (và cú pháp không chính xác) về những gì tôi đang cố gắng để làm sẽ như thế này

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 

Trả lời

3

Thêm vào đó, trên thực tế có một phương pháp WaitAll mà đợi cho tất cả các kết quả và lợi nhuận khi tất cả HTTPCliens đã hoàn thành đưa phản hồi. Tôi đã gửi sự khác biệt trong chi nhánh lốc xoáy của tôi (https://github.com/pranjal5215/tornado). Tôi đã thêm một lớp WaitAny là WaitAll không đồng bộ và trả về kết quả ngay sau khi một trong những HTTPClient đã trả về kết quả.

Diff là tại (https://github.com/pranjal5215/tornado/commit/dd6902147ab2c5cbf2b9c7ee9a35b4f89b40790e), (https://github.com/pranjal5215/tornado/wiki/Add-WaitAny-to-make-WaitAll-return-results-incrementally)

sử dụng

mẫu:

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

Đó là trường hợp, khi bạn không nên sử dụng inline callbacks, tức là gen. Ngoài ra self.render sẽ được gọi sau khi tất cả các cuộc gọi lại đã hoàn tất. Nếu bạn muốn trả lời một phần từ máy chủ - hãy trả lời một phần.

suy nghĩ theo cách này (nó chỉ ý tưởng với phòng lớn của cải):

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) 
Các vấn đề liên quan