我正在将大文件从/向存储器传输,我使用了chunked请求和chunked响应.
对于块请求,我在我的actor中使用内置的ack机制来确保在发送更多内容之前已经编写了每个块:
connection ! MessageChunk(data).withAck(ChunkSent)
连接是Spray和Akka提供的IO actor,然后我可以在发送下一个块之前等待ChunkSent.好.
我正在努力用chunked响应重现相同的行为.我可以发送我的HttpRequest,然后接收一个ChunkedResponseStart,然后是一堆MessageChunks,最后是一个ChunkedMessageEnd但是有没有办法强制Spray等待我在发送下一个MessageChunk之后发送一个ack?
编辑:只是为了更清楚一点:在这种情况下我使用spray-can作为客户端,我不是服务器,服务器是我之前提到的存储.
解决方法
但是,您可以将Tcp.SuspendReading和Tcp.ResumeReading命令发送到客户端连接(块的发送方),以指示Akka IO TCP层在您超载时停止读取.请参阅此proof-of-concept,它尝试在SuspendReading / ResumeReading之上添加Acking作为接收方(对于服务器但对于客户端应该类似),以获取有关如何使用当前版本的spray构建内容的提示.
这种情况显然不是最佳的,因为特别是在负载1)你需要弄清楚你是否超载2)这些消息可能会被卡在TCP连接的消息队列中,然后才能处理它们.
有两件事可以改善未来的情况:
>由于最近Akka IO支持“拉模式”,其中TCP连接只读取一次,然后等待Tcp.ResumeReading命令(基本上是Ack).但是,这不适用于喷雾(可能不会).>我们现在关注的Akka HTTP是流媒体支持.计划是引入一个新的API(我们在spray-can中所使用的),它可以自然地为HTTP工作流,并支持自动背压支持,而无需额外的用户代码来支持它.唉,还没有准备好.