Я немного экспериментировал с экспериментальным API Akka Streams, и у меня есть прецедент, который я хотел бы увидеть, как реализовать. Для моего варианта использования у меня есть StreamTcp
Flow
, который подается от привязки входного потока подключений к моему серверному сокету. Поток, который у меня есть, основан на данных ByteString
, входящих в него. Данные, которые поступают, будут иметь разделитель в нем, что означает, что я должен рассматривать все до разделителя как одно сообщение и все после следующего и следующего следующего разделителя в качестве следующего сообщения. Поэтому, играя с более простым примером, не используя сокеты и только статический текст, это то, что я придумал:
import akka.actor.ActorSystem
import akka.stream.{ FlowMaterializer, MaterializerSettings }
import akka.stream.scaladsl.Flow
import scala.util.{ Failure, Success }
import akka.util.ByteString
object BasicTransformation {
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("Sys")
val data = ByteString("Lorem Ipsum is simply.Dummy text of the printing.And typesetting industry.")
Flow(data).
splitWhen(c => c == '.').
foreach{producer =>
Flow(producer).
filter(c => c != '.').
fold(new StringBuilder)((sb, c) => sb.append(c.toChar)).
map(_.toString).
filter(!_.isEmpty).
foreach(println(_)).
consume(FlowMaterializer(MaterializerSettings()))
}.
onComplete(FlowMaterializer(MaterializerSettings())) {
case any =>
system.shutdown
}
}
}
Основная функция на Flow
, которую я нашел для достижения моей цели, была splitWhen
, которая затем создает дополнительные подпотоки, по одному для каждого сообщения на разделитель .
. Затем я обрабатываю каждый подпоток с другим конвейером шагов, наконец печатая отдельные сообщения в конце.
Все это кажется немного многословным, чтобы выполнить то, что я считал довольно простым и распространенным вариантом использования. Поэтому мой вопрос: есть ли более чистый и менее верный способ сделать это или это правильный и предпочтительный способ разделить поток на разделитель?