Потоковая передача ByteArrayOutputStream в ответ akka http
Я создаю ByteArrayOutputStream, используя ZIO Streams, т.е.:
lazy val byteArrayOutputStream = new ByteArrayOutputStream()
val sink = ZSink.fromOutputStream(byteArrayOutputStream).contramapChunks[String](_.flatMap(_.getBytes)
val data = ZStream.unwrap(callToFunction).run(sink)
Это отлично работает - теперь мне нужно передать эти данные обратно клиенту, используя akka http. Я могу сделать это:
val arr = byteArrayOutputStream.toByteArray
complete(HttpEntity(ContentTypes.`application/octet-stream`, arr)
который работает, но, конечно, toByteArray переносит поток вывода в память, т.е. я не передаю данные. Мне не хватает чего-то очевидного - есть ли простой способ сделать это?
1 ответ
Вы можете конвертировать выходной поток в Akka Stream
Source
:
val byteArrayOutputStream = new ByteArrayOutputStream()
val source = StreamConverters.asOutputStream().mapMaterializedValue(_ => byteArrayOutputStream)
а затем просто создайте фрагментированный объект HTTP:
HttpResponse(entity = HttpEntity.Chunked.fromData(ContentTypes.`application/octet-stream`, source))
Подробнее о передаче по частям: https://datatracker.ietf.org/doc/html/rfc7230#section-4.1
Для ZIO вы, вероятно, могли бы использовать что-то вроде этого:
val zSource = ZStream.fromOutputStreamWriter(os => byteArrayOutputStream.writeTo(os))
Однако вам нужно найти способ конвертировать ZStream в Akka Stream Source.