在 akka-http 中,当响应不是 200 时,是否需要在接收器中消耗响应实体?
In akka-http, do response entities need to be consumed in a sink when the response is anything other than 200?
这个akka-http documentation page底部有一个警告:
Be sure to consume the response entities
dataBytes:Source[ByteString,Unit]
by for example connecting it to a
Sink (for example response.entity.dataBytes.runWith(Sink.ignore)
if
you don't care about the response entity), since otherwise Akka HTTP
(and the underlying Streams infrastructure) will understand the lack
of entity consumption as a back-pressure signal and stop reading from
the underlying TCP connection!
This is a feature of Akka HTTP that allows consuming entities (and
pulling them through the network) in a streaming fashion, and only on
demand when the client is ready to consume the bytes - it may be a bit
suprising at first though.
为什么在响应的状态代码不是 StatusCodes.OK
的情况下不需要这样做?还是实际上需要它,而该页面(也在下面)上显示的代码示例缺少它?
def receive = {
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
log.info("Got response, body: " + entity.dataBytes.runFold(ByteString(""))(_ ++ _))
case HttpResponse(code, _, _, _) =>
//why not here?
log.info("Request failed, response code: " + code)
}
应始终使用响应实体,但在实践中,错误响应通常是 HttpEntity.Strict
类型,无法使用这些实体不会导致任何背压问题。
对于感兴趣的人,从 Akka 2.4.9 开始,此行为来自 SlotProcessor.running
where it wraps the HttpEntity
using HttpEntity.captureTermination
。这种包装用于发出响应已被消耗的信号,从而提供正确的背压信号。对于 HttpEntity.Strict
因为实体主体已经在内存中 captureTermination
方法将 return 一个 Future.success(())
而其他类型将包装 Source
和 return 一个 Future
在基础 Source
完成时完成。
关于 HttpEntity
类型 returned,就 API 而言,不能保证某些响应将是 HttpEntity.Strict
这就是为什么建议总是使用响应。 HttpResponseParser 正在做解析响应的工作。据我了解,如果正文已读入内存(基于缓冲区大小)并且没有传输编码,那么在读取响应时可以 HttpEntity.Strict
编辑 return,因为我们已经完成了所有操作工作。否则 HttpEntity.Default
或 HttpEntity.Chunked
将被 returned.
在最后一次捕获时,如果您使用 HttpEntity
作为服务器响应的一部分(例如,在 complete
指令中),那么服务器可能会超时并且不会使用实体。在这种情况下,您可以使用 withRequestTimeoutResponse
指令来使用响应。
这个akka-http documentation page底部有一个警告:
Be sure to consume the response entities
dataBytes:Source[ByteString,Unit]
by for example connecting it to a Sink (for exampleresponse.entity.dataBytes.runWith(Sink.ignore)
if you don't care about the response entity), since otherwise Akka HTTP (and the underlying Streams infrastructure) will understand the lack of entity consumption as a back-pressure signal and stop reading from the underlying TCP connection!This is a feature of Akka HTTP that allows consuming entities (and pulling them through the network) in a streaming fashion, and only on demand when the client is ready to consume the bytes - it may be a bit suprising at first though.
为什么在响应的状态代码不是 StatusCodes.OK
的情况下不需要这样做?还是实际上需要它,而该页面(也在下面)上显示的代码示例缺少它?
def receive = {
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
log.info("Got response, body: " + entity.dataBytes.runFold(ByteString(""))(_ ++ _))
case HttpResponse(code, _, _, _) =>
//why not here?
log.info("Request failed, response code: " + code)
}
应始终使用响应实体,但在实践中,错误响应通常是 HttpEntity.Strict
类型,无法使用这些实体不会导致任何背压问题。
对于感兴趣的人,从 Akka 2.4.9 开始,此行为来自 SlotProcessor.running
where it wraps the HttpEntity
using HttpEntity.captureTermination
。这种包装用于发出响应已被消耗的信号,从而提供正确的背压信号。对于 HttpEntity.Strict
因为实体主体已经在内存中 captureTermination
方法将 return 一个 Future.success(())
而其他类型将包装 Source
和 return 一个 Future
在基础 Source
完成时完成。
关于 HttpEntity
类型 returned,就 API 而言,不能保证某些响应将是 HttpEntity.Strict
这就是为什么建议总是使用响应。 HttpResponseParser 正在做解析响应的工作。据我了解,如果正文已读入内存(基于缓冲区大小)并且没有传输编码,那么在读取响应时可以 HttpEntity.Strict
编辑 return,因为我们已经完成了所有操作工作。否则 HttpEntity.Default
或 HttpEntity.Chunked
将被 returned.
在最后一次捕获时,如果您使用 HttpEntity
作为服务器响应的一部分(例如,在 complete
指令中),那么服务器可能会超时并且不会使用实体。在这种情况下,您可以使用 withRequestTimeoutResponse
指令来使用响应。