Akka Stream的“保持左/右/两者"如何产生不同的输出? [英] How does Akka Stream's Keep right/left/both result in a different output?

查看:193
本文介绍了Akka Stream的“保持左/右/两者"如何产生不同的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力解决Keep在Akka流中的工作方式.在保持akka流意味着什么中阅读答案,我了解到它有助于控制我们从实现器的左侧/右侧/两侧获取结果.但是,如果可以更改left/right的值并获得不同的结果,我仍然无法构建示例.

I am trying to wrap my head around how Keep works in Akka streams. Reading answers in What does Keep in akka stream mean, I understand that it helps to control we get the result from the left/right/both sides of the materializer. However, I still can't build an example were I can change the value of left/right and get different results.

例如,

implicit val system: ActorSystem = ActorSystem("Playground")
implicit val materializer: ActorMaterializer = ActorMaterializer()

val sentenceSource = Source(List(
  "Materialized values are confusing me",
  "I love streams",
  "Left foo right bar"
))

val wordCounter = Flow[String].fold[Int](0)((currentWords, newSentence) => currentWords + newSentence.split(" ").length)
val result = sentenceSource.viaMat(wordCounter)(Keep.left).toMat(Sink.head)(Keep.right).run()

val res = Await.result(result, 2 second)
println(res)

在此示例中,如果将值从保持左"更改为保持右",我仍然会得到相同的结果.有人可以给我提供一个基本示例,其中更改为保持左/右/两个值会导致不同的结果吗?

In this example if I change values from keep left to keep right, I still get the same result. Can someone provide me with a basic example where changing keep to left/right/both values results in a different outcome?

推荐答案

在您的示例中,由于:

sentenceSource: akka.stream.scaladsl.Source[String,akka.NotUsed] = ???
wordCounter: akka.stream.scaladsl.Flow[String,Int,akka.NotUsed] = ???

两者都具有NotUsed作为其实现(表示它们没有有用的实现),

both have NotUsed as their materialization (indicating that they don't have a useful materialization),

sentenceSource.viaMat(wordCounter)(Keep.right)
sentenceSource.viaMat(wordCounter)(Keep.left)

具有相同的实现.但是,由于Sink.head[T]实现为Future[T],因此更改组合器显然会产生影响

have the same materialization. However, since Sink.head[T] materializes to Future[T], changing the combiner clearly has an impact

val intSource = sentenceSource.viaMat(wordCounter)(Keep.right)

val notUsed = intSource.toMat(Sink.head)(Keep.left)
// akka.stream.scaladsl.RunnableGraph[akka.NotUsed]

val intFut = intSource.toMat(Sink.head)(Keep.right)
// akka.stream.scaladsl.RunnableGraph[scala.concurrent.Future[Int]]

notUsed.run    // akka.NotUsed

intFut.run     // Future(Success(12))

Source中的大多数源都具体化为NotUsed,几乎所有常见的Flow运算符也都实现了,因此toMat(someSink)(Keep.right)(或等效的.runWith(someSink))比使用Keep.left更为普遍. >或Keep.both.源/流实现的最常见用例是提供某种控制平面,例如:

Most of the sources in Source materialize to NotUsed and nearly all of the common Flow operators do as well, so toMat(someSink)(Keep.right) (or the equivalent .runWith(someSink)) is far more prevalent than using Keep.left or Keep.both. The most common usecases for source/flow materialization are to provide some sort of control plane, such as:

import akka.Done
import akka.stream.{ CompletionStrategy, OverflowStrategy }

import system.dispatcher

val completionMatcher: PartialFunction[Any, CompletionStrategy] = { case Done => CompletionStrategy.draining }
val failureMatcher: PartialFunction[Any, Throwable] = { case 666 => new Exception("""\m/""") }

val sentenceSource = Source.actorRef[String](completionMatcher = completionMatcher, failureMatcher = failureMatcher, bufferSize = 100, overflowStrategy = OverflowStrategy.dropNew)

// same wordCounter as before
val stream = sentenceSource.viaMat(wordCounter)(Keep.left).toMat(Sink.head)(Keep.both)    // akka.stream.scaladsl.RunnableGraph[(akka.actor.ActorRef, scala.concurrent.Future[Int])]

val (sourceRef, intFut) = stream.run()

sourceRef ! "Materialized values are confusing me"
sourceRef ! "I love streams"
sourceRef ! "Left foo right bar"
sourceRef ! Done

intFut.foreach { result =>
  println(result)
  system.terminate()
}

在这种情况下,我们使用Keep.left传递sentenceSource的物化值,然后使用Keep.both来获得该物化值和Sink.head的物化值.

In this case, we use Keep.left to pass through sentenceSource's materialized value and then Keep.both to get both that materialized value and that of Sink.head.

这篇关于Akka Stream的“保持左/右/两者"如何产生不同的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆