2016-05-17 19 views
2

私のtornado APIコールは、別のURLを呼び出してから、結果をクライアントにストリーミングします。ただし、内部URLからエラーコードが返された場合は、独自のエラーを個別に処理し、エラー内容をクライアントにストリームしたいと考えています。私が現在持っていることはこれです:レスポンスコードを同期して処理する際に、どのように非同期的にトルネードでストリーミングデータを処理するのですか?

@web.asynchronous 
@gen.coroutine 
def get(self, job_id): 
    url = ... 
    client = httpclient.AsyncHTTPClient() 

    # handle_chunk will forward received bytes to the client, allowing 
    # other HTTP requests to be handled concurrently 
    response = yield client.fetch(httpclient.HTTPRequest(
     url=url, 
     streaming_callback=self._handle_chunk)) 
    self.finish() 

def _handle_chunk(self, chunk): 
    self.write(chunk) 
    self.flush() 

私は応答コードが200家族であるが、全体の要求が完了するまで応答がclient.fetchによって得られたされていない場合は、転送チャンクを起動するだけにこれを変更する必要があります。どのようにこれを行うにはどのようなアイデア?

答えて

4

streaming_callbackheader_callbackの両方を使用してください。ヘッダーコールバックは、最初の呼び出しがstreaming_callbackになる前に実行され、ヘッダーは文字列のリストとして表示されます。ヘッダーには、あなた自身を解析する必要がありますステータス行で始まる:

@gen.coroutine 
def get(self, job_id): 
    url = ... 
    client = httpclient.AsyncHTTPClient() 

    response = yield client.fetch(httpclient.HTTPRequest(
     url=url, 
     header_callback=self._handle_headers, 
     streaming_callback=self._handle_chunk)) 
    if response.code != 200: 
     # handle error 
    self.finish() 

def _handle_headers(self, headers): 
    self._start_line = tornado.httputil.parse_response_start_line(headers[0]) 

def _handle_chunk(self, chunk): 
    if self._start_line.code == 200: 
     self.write(chunk) 
     self.flush() 

それはきれいに要求をキャンセルすることはできません。ステータスコードが200ではない場合、コールバックはストリーミングチャンクを受け入れ、無視します(そして、別の場所でエラーを返します)。

+0

'header_callback'は' streaming_callback'コールの前に呼び出されることが保証されていますか? – Lucretiel

+1

はい、header_callbackは常に最初のstreaming_callbackの前に呼び出されます。 (接続が成功した場合、接続が行われる前にエラーが発生した場合、 'yield client.fetch()'はどちらのコールバックも呼び出さずにエラーを発生させます) –

+0

古い答えにコメントを投稿しないでください。新しい質問を投稿してください。 –

関連する問題