Потоковая передача 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.

Другие вопросы по тегам