Как я могу обрабатывать потоковые данные в tornado асинхронно, одновременно обрабатывая код ответа синхронно?
Мой вызов API tornado вызовет другой 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, пока не будет завершен весь запрос. Есть идеи, как это сделать?
1 ответ:
Используйте как
streaming_callback, так иheader_callback. Обратный вызов заголовка будет выполняться перед первым вызовомstreaming_callback, причем заголовки будут представлены в виде списка строк. Заголовки начинаются со строки состояния, которую вы должны будете разобрать самостоятельно:В настоящее время невозможно полностью отменить запрос; если код состояния не равен 200, ваш обратный вызов должен будет принять потоковые фрагменты и игнорировать их (а затем вы вернете ошибку в другом месте).@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()
Comments