akka流中的流问题

时间:2017-01-29 18:28:10

标签: akka akka-stream

我在Akka流程中很新,我一直在使用Rx一段时间,所以我对所有运算符都很了解,但我不知道为什么我的管道没有发出值

这是我的代码

  @Test def mainFlow(): Unit = {
    val increase = Flow[Int]
      .map(value => value * 10)
    val filterFlow = Flow[Int]
      .filter(value => value > 50)
      .take(2)
    Source(0 to 10)
      .via(increase)
      .via(filterFlow)
      .to(Sink.foreach(value => println(s"Item emitted:$value")))
      .run()
  }

第一个Flow变换Source中发出的值乘以10,第二个流过滤器只获取高于50的项目然后我得到2,所以我期望在Sink 60和70中 但没有发出任何东西。

知道为什么吗?

2 个答案:

答案 0 :(得分:3)

您的流程已正确构建,并发出您提到的那两个元素。 我相信问题出在你的考试中。也就是说,流程是异步运行的,您的测试是一个简单的Unit过程。因此,测试不会等到流程运行。

您需要在测试中引入一些同步来执行断言。一种方法是使用ScalaTest中的ScalaFutures特征,它为您提供futureValue方法。

val increase = Flow[Int]
  .map(value => value * 10)
val filterFlow = Flow[Int]
  .filter(value => value > 50)
  .take(2)
Source(0 to 10)
  .via(increase)
  .via(filterFlow)
  .runForeach(value => println(s"Item emitted:$value"))
  .futureValue

请注意,.to(Sink.foreach{...}).run()不会公开您需要同步的Future[Done]。您的代码需要更改为.toMat(Sink.foreach{...})(Keep.right).run(),可以缩写为.runForeach(...)

答案 1 :(得分:1)

因为您所说的是以下内容:

对于数字1..10,将它们乘以10,但只产生2个第一个元素,然后保留所有大于50的元素,然后打印它们。

此外,您的测试不会等待RunnableFlow的完成,这通常意味着您的程序将在流有机会运行之前退出(Akka Streams以异步方式运行)。

请注意,对于您的示例,没有理由使用GraphDSL,您的代码与以下内容相同:

Source(1 to 10).map(_ * 10).take(2).filter(_ > 50).runForeach(println)

但是因为它并没有真正做任何“有意义的异步”,我认为你会更好:

(1 to 10).map(_ * 10).take(2).filter(_ > 50).foreach(println)

但是再次,使用代码的当前状态,它等同于以下表达式:

()