2016-05-17 1 views
2

Мой вызов 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_callback, так и header_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

Пожалуйста, не оставляйте комментарии по старым ответам с совершенно новыми вопросами для обсуждения , Отправьте новый вопрос. –

 Смежные вопросы

  • Нет связанных вопросов^_^