Я прочитал кое-что о возможности отправки файла на S3 через Iteratee, что, по-видимому, позволяет отправлять так S3-фрагменты файла по мере их получения и избегать OutOfMemory для больших файлов, например.
Я нашел этот пост SO, который, вероятно, почти то, что мне нужно сделать: Play 2.x: Загрузка активного файла с помощью Iteratees Я действительно не понимаю, как это сделать, или если это действительно доступно в Play 2.0.2 (потому что Садек Броди говорит, что 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. Я действительно могу переслать 500-мегабайтный файл на S3 неблокирующим способом с очень низким потреблением памяти без использования Iteratees, используя Java + AsyncHttpClient + Grizzly (но, я думаю, он также будет работать с Netty).
Итак, какое преимущество использования Iteratee?
Единственное отличие, которое я вижу, это то, что InputStream, который я получаю и пересылаю на S3, в моем случае поддерживается временным файлом (это поведение CXF), поэтому он может быть не так реактивным, как Play Iteratee
Но с помощью Iteratees, если Enumerator создает байты, полученные соединением, и перенаправляет их на S3 через Iteratee, тогда, если соединение с S3 не является хорошим, и байты не могут быть перенаправлены очень быстро, где хранятся "ожидающие" байты?