Leiten Sie einen Datei-Upload-Stream mit Play2 / Scala über Iteratee an S3 weiter
Ich habe einiges über die Möglichkeit gelesen, eine Datei über Iteratee an S3 zu senden. Dies scheint zu ermöglichen, S3-Teile einer Datei so zu senden, wie wir sie erhalten, und beispielsweise ein OutOfMemory für große Dateien zu vermeiden.
Ich habe diesen SO-Beitrag gefunden, der wahrscheinlich fast das ist, was ich tun muss:Play 2.x: Reaktives Hochladen von Dateien mit Iteraten Ich verstehe nicht wirklich, wie es geht, oder ob es wirklich in Play 2.0.2 verfügbar ist (da Sadek Brodi sagt, dass foldM nur zum Beispiel in Play 2.1 verfügbar ist)
Kann jemand dies auf einfache Weise erklären, für jemanden, der einen Blog über Iteratees gelesen hat und noch kein Scala / Play2-Experte ist?
Ich weiß nicht einmal, ob ich einen mehrteiligen Body-Parser oder ähnliches verwenden soll, aber ich weiß, dass ich nicht verstehe, was dieser Code tut:
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(_)))
Was ist übrigens der Unterschied im Speicherverbrauch im Vergleich zur Verwendung von klassischem Java InputStream / OutputStream? Ich bin tatsächlich in der Lage, eine 500-MB-Datei blockierungsfrei mit sehr geringem Speicherverbrauch ohne Verwendung von Iteratees mit Java + AsyncHttpClient + Grizzly an S3 weiterzuleiten (aber ich denke, es würde auch mit Netty funktionieren).
Was ist der Vorteil von Iteratee?
Ein Unterschied, den ich sehe, ist, dass der InputStream, den ich erhalte und an S3 weiterleite, in meinem Fall durch eine temporäre Datei gesichert ist (dies ist ein CXF-Verhalten), so dass er möglicherweise nicht so reaktiv ist wie Play Iteratee
Wenn der Enumerator bei Iteraten jedoch die von der Verbindung empfangenen Bytes erzeugt und über einen Iteraten an S3 weiterleitet, ist die Verbindung zu S3 nicht gut und die Bytes können nicht sehr schnell weitergeleitet werden. In diesem Fall werden die "anstehenden" Bytes gespeichert ?