2012-08-10 23 views
5

私はtornado.genモジュールのドキュメントから理解して何から結果を返すには、tornado.gen.Taskが一意のキーに関連付けられている各コールバック/待機組とtornado.gen.Callbackとtornado.gen.Waitで含むことです。 ..トルネード非同期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") 

したがって、上記のコードは異なるURLからのすべての応答を取得します。 は、今私が実際に達成するために必要なものとすぐhttp_clientがデータを返すものとして応答を返すことです。 「tornadoweb.org」の最初のデータを返すのであれば、それが完了するために、他のhttp_clientsを待っておく必要がありself.write(respose)とdefの取得のループ()を行う必要があります。この使用tornado.genインターフェイスを作成する方法について 任意のアイデア。私はすなわちあなたがinline callbacksを使うべきではありませんそれはケースだこの

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

、実際にすべてのHTTPCliensが与え完了したとき、すべての結果を返すのを待つ方法WaitAllがあります反応。 私は竜巻のブランチ(https://github.com/pranjal5215/tornado)で差分を提出しています。私は非同期WaitAllであるクラスWaitAnyを追加し、1つのHTTPClientが結果を返すとすぐに結果を返します。

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

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)