我已经阅读了一些关于通过 Iteratee 将文件发送到 S3 的可能性的内容,这似乎允许在我们收到文件时发送 S3 文件块,并避免大文件的 OutOfMemory 例如。
我发现这篇 SO 帖子可能几乎是我需要做的: Play 2.x : Reactive file upload with Iteratees 我真的不明白怎么做,或者它是否真的在 Play 2.0.2 中可用(因为 Sadek Brodi 说 foldM 仅在 Play 2.1 中可用)
对于阅读过一些关于 Iteratees 的博客但还不是 Scala/Play2 专家的人,有人可以用简单的方式解释一下吗?
我什至不知道我是否应该使用多部分正文解析器或类似的东西,但我知道的一件事是我不明白这段代码在做什么:
val consumeAMB =
Traversable.takeUpTo[Array[Byte]](1028*1028) &>> Iteratee.consume()
val rechunkAdapter:Enumeratee[Array[Byte],Array[Byte]] =
Enumeratee.grouped(consumeAMB)
val writeToStore: Iteratee[Array[Byte],_] =
Iteratee.foldM[Array[Byte],_](connectionHandle){ (c,bytes) =>
// write bytes and return next handle, probable in a Future
}
BodyParser( rh => (rechunkAdapter &>> writeToStore).map(Right(_)))
顺便说一句,与使用经典的 Java InputStream / OutputStream 相比,内存消耗会有什么不同。我实际上能够以非阻塞方式将 500mb 文件转发到 S3,内存消耗非常低,不使用 Iteratees,使用 Java + AsyncHttpClient + Grizzly(但我想它也适用于 Netty)。
那么使用Iteratee有什么好处呢?
我可以看到的一个区别是,我获得并转发到 S3 的 InputStream 在我的情况下由一个临时文件支持(这是一种 CXF 行为),因此它可能不像 Play Iteratee 那样具有反应性
但是对于 Iteratee,如果 Enumerator 产生连接接收到的字节并通过 Iteratee 将它们转发到 S3,那么如果与 S3 的连接不好并且字节不能非常快速地转发,那么“待处理”字节存储在哪里?