来自一个阻塞迭代器的多个Akka源?

时间:2018-05-31 07:33:59

标签: scala akka-stream

我有一个迭代器,它从InputStream中读取二进制记录(阻塞新输入),并生成具有三种可能类型之一的元素,假设类型为T1,T2,T3。

根据消息类型从该迭代器生成3个独立的Akka Sources S1,S2和S3的最简单方法是什么?

每个源将由不同的库函数使用,每个库函数都需要Source作为输入。

2 个答案:

答案 0 :(得分:0)

一个想法是使用PartitionHub。例如:

View view = getLayoutInflater().inflate(R.layout.chooser_bottom_sheet, null);
BottomSheetDialog dialog = new BottomSheetDialog(this,R.style.BottomSheetDialog); // Style here
dialog.setContentView(view);
dialog.show();

在上面的示例中,import akka.NotUsed import akka.actor.ActorSystem import akka.stream._ import akka.stream.scaladsl._ implicit val system = ActorSystem("Terminator") implicit val materializer = ActorMaterializer() sealed trait T case class T1(id: Int) extends T case class T2(id: Int) extends T case class T3(id: Int) extends T val partitioner: (Int, T) => Int = (num, t) => t match { case t: T1 => 0 case t: T2 => 1 case t: T3 => 2 } val producer: Source[T, NotUsed] = Source.fromIterator(() => Iterator.from(1).map { case i if i % 2 == 0 => T2(i) case i if i % 3 == 0 => T3(i) case i => T1(i) }) val fromProducer: Source[T, NotUsed] = producer.toMat(PartitionHub.sink( partitioner, startAfterNrOfConsumers = 3, bufferSize = 256) )(Keep.right) .run() fromProducer.runForeach(msg => println(s"consumer1: $msg")) fromProducer.runForeach(msg => println(s"consumer2: $msg")) fromProducer.runForeach(msg => println(s"consumer3: $msg")) producer,可生成SourceT1T2类型的元素。 T3创建一个PartitionHub,根据元素的类型将这些元素路由到三个消费者。此Sink作为具体化值Sink(上面命名为Source)返回,其本身可以多次实现:该示例实现fromProducer三次并简单地打印元素。每个实现都可以使用您想要的任何fromProducer

答案 1 :(得分:0)

对迭代器进行分区

您可以在创建任何akka Iterator值之前对基础Source进行分区。

首先处理数据:

sealed Trait Data

case class Foo() extends Data
case class Bar() extends Data
case class Baz() extends Data

密封的特性现在可用于分区功能:

val isAFoo : Data => Boolean = _ match {
  case _ : Foo => true
  case _       => false
}

val isABar : Data => Boolean = _ match {
  case _ : Bar => true
  case _       => false
}

现在可以对Iterator进行分区:

val sourceIterator : Iterator[Data] = ???

val (fooIterator, notFooIterator) = sourceIterator partition isAFoo

val (barIterator, bazIterator) = notFooIterator partition isABar

这些迭代器值可以提供不同的来源:

val fooSource : Source[Foo, _] = Source.fromIterator(() => fooIterator)

val barSource : Source[Bar, _] = Source.fromIterator(() => barIterator)

val bazSource : Source[Baz, _] = Source.fromIterator(() => bazIterator)