Iteratee を介してファイルを S3 に送信する可能性についていくつか読んだことがあります。これにより、ファイルを受信したときにファイルの S3 チャンクを送信し、たとえば大きなファイルの OutOfMemory を回避できるようです。
おそらく私がする必要があるこの SO 投稿を見つけました: Play 2.x : Reactive file upload with Iteratees Sadek Brodi は、foldM は Play 2.1 で利用可能であると述べているため、例としてのみ)
Iteratees についてのブログを読んだことがあり、まだ Scala/Play2 の専門家ではない人のために、誰かがこれを簡単に説明できますか?
マルチパート ボディ パーサーなどを使用する必要があるかどうかもわかりませんが、このコードが何をしているのか理解できないことが 1 つあります。
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を使用した場合と比較して、メモリ消費量の違いはどうなるでしょうか。私は実際に、Java + AsyncHttpClient + Grizzly を使用して、Iteratees を使用せずに、非常に低いメモリ消費量で非ブロッキングの方法で 500 MB のファイルを S3 に転送できます (ただし、Netty でも動作すると思います)。
では、Iteratee を使用する利点は何でしょうか?
私が見ることができる 1 つの違いは、取得して S3 に転送する InputStream は、私の場合、一時ファイル (これは CXF の動作です) によってサポートされているため、Play Iteratee ほど反応的ではない可能性があることです。
しかし、Iteratee では、Enumerator が接続によって受信されたバイトを生成し、Iteratee を介して S3 に転送する場合、S3 への接続が良好ではなく、バイトを非常に高速に転送できない場合、「保留中」のバイトが格納されます。 ?