- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 akka-streams 的新手,不知道如何解决这个问题。
我有 3 个源流按序列 ID 排序。我想将具有相同 ID 的值组合在一起。每个流中的值可能丢失或重复。如果一个流比其他流的生产者更快,则它应该受到背压。
case class A(id: Int)
case class B(id: Int)
case class C(id: Int)
case class Merged(as: List[A], bs: List[B], cs: List[C])
import akka.stream._
import akka.stream.scaladsl._
val as = Source(List(A(1), A(2), A(3), A(4), A(5)))
val bs = Source(List(B(1), B(2), B(3), B(4), B(5)))
val cs = Source(List(C(1), C(1), C(3), C(4)))
val merged = ???
// value 1: Merged(List(A(1)), List(B(1)), List(C(1), C(1)))
// value 2: Merged(List(A(2)), List(B(2)), Nil)
// value 3: Merged(List(A(3)), List(B(3)), List(C(3)))
// value 4: Merged(List(A(4)), List(B(4)), List(C(4)))
// value 5: Merged(List(A(5)), List(B(5)), Nil)
// (end of stream)
最佳答案
这个问题很老,但我试图找到一个解决方案,我只在 lightbend forum 处遇到了通往路径的岩石。 ,但不是一个有效的用例。所以我决定在这里实现并发布我的例子。
我创建了 3 个来源 sourceA
, sourceB
, 和 sourceC
使用 .throttle()
以不同的速度发出事件.然后我创建了一个 RunnableGraph
我使用 Merge
合并源我输出到我的 WindowGroupEventFlow
Flow
我基于事件数量的滑动窗口实现的。这是图表:
sourceA ~> mergeShape.in(0)
sourceB ~> mergeShape.in(1)
sourceC ~> mergeShape.in(2)
mergeShape.out ~> windowFlowShape ~> sinkShape
我在源代码上使用的类是:
object Domain {
sealed abstract class Z(val id: Int, val value: String)
case class A(override val id: Int, override val value: String = "A") extends Z(id, value)
case class B(override val id: Int, override val value: String = "B") extends Z(id, value)
case class C(override val id: Int, override val value: String = "C") extends Z(id, value)
case class ABC(override val id: Int, override val value: String) extends Z(id, value)
}
这是
WindowGroupEventFlow
Flow
我创建以对事件进行分组:
// step 0: define the shape
class WindowGroupEventFlow(maxBatchSize: Int) extends GraphStage[FlowShape[Domain.Z, Domain.Z]] {
// step 1: define the ports and the component-specific members
val in = Inlet[Domain.Z]("WindowGroupEventFlow.in")
val out = Outlet[Domain.Z]("WindowGroupEventFlow.out")
// step 3: create the logic
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) {
// mutable state
val batch = new mutable.Queue[Domain.Z]
var count = 0
// var result = ""
// step 4: define mutable state implement my logic here
setHandler(in, new InHandler {
override def onPush(): Unit = {
try {
val nextElement = grab(in)
batch.enqueue(nextElement)
count += 1
// If window finished we have to dequeue all elements
if (count >= maxBatchSize) {
println("************ window finished - dequeuing elements ************")
var result = Map[Int, Domain.Z]()
val list = batch.dequeueAll(_ => true).to[collection.immutable.Iterable]
list.foreach { tuple =>
if (result.contains(tuple.id)) {
val abc = result.get(tuple.id)
val value = abc.get.value + tuple.value
val z: Domain.Z = Domain.ABC(tuple.id, value)
result += (tuple.id -> z)
} else {
val z: Domain.Z = Domain.ABC(tuple.id, tuple.value)
result += (tuple.id -> z)
}
}
val finalResult: collection.immutable.Iterable[Domain.Z] = result.map(p => p._2)
emitMultiple(out, finalResult)
count = 0
} else {
pull(in) // send demand upstream signal, asking for another element
}
} catch {
case e: Throwable => failStage(e)
}
}
})
setHandler(out, new OutHandler {
override def onPull(): Unit = {
pull(in)
}
})
}
// step 2: construct a new shape
override def shape: FlowShape[Domain.Z, Domain.Z] = FlowShape[Domain.Z, Domain.Z](in, out)
}
这就是我运行一切的方式:
object WindowGroupEventFlow {
def main(args: Array[String]): Unit = {
run()
}
def run() = {
implicit val system = ActorSystem("WindowGroupEventFlow")
import Domain._
val sourceA = Source(List(A(1), A(2), A(3), A(1), A(2), A(3), A(1), A(2), A(3), A(1))).throttle(3, 1 second)
val sourceB = Source(List(B(1), B(2), B(1), B(2), B(1), B(2), B(1), B(2), B(1), B(2))).throttle(2, 1 second)
val sourceC = Source(List(C(1), C(2), C(3), C(4))).throttle(1, 1 second)
// Step 1 - setting up the fundamental for a stream graph
val windowRunnableGraph = RunnableGraph.fromGraph(
GraphDSL.create() { implicit builder =>
import GraphDSL.Implicits._
// Step 2 - create shapes
val mergeShape = builder.add(Merge[Domain.Z](3))
val windowEventFlow = Flow.fromGraph(new WindowGroupEventFlow(5))
val windowFlowShape = builder.add(windowEventFlow)
val sinkShape = builder.add(Sink.foreach[Domain.Z](x => println(s"sink: $x")))
// Step 3 - tying up the components
sourceA ~> mergeShape.in(0)
sourceB ~> mergeShape.in(1)
sourceC ~> mergeShape.in(2)
mergeShape.out ~> windowFlowShape ~> sinkShape
// Step 4 - return the shape
ClosedShape
}
)
// run the graph and materialize it
val graph = windowRunnableGraph.run()
}
}
您可以在输出中看到我如何对具有相同 ID 的元素进行分组:
sink: ABC(1,ABC)
sink: ABC(2,AB)
************ window finished - dequeuing elements ************
sink: ABC(3,A)
sink: ABC(1,BA)
sink: ABC(2,CA)
************ window finished - dequeuing elements ************
sink: ABC(2,B)
sink: ABC(3,AC)
sink: ABC(1,BA)
************ window finished - dequeuing elements ************
sink: ABC(2,AB)
sink: ABC(3,A)
sink: ABC(1,BA)
关于scala - Akka Streams 自定义合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36723884/
我正在尝试实现具有以下签名的方法: public static Pair, Stream> flatten(Iterator, Stream>> iterator); 该方法的目标是将每种流类型展平
我有两个流从两个不同的 api 获取。 Stream get monthOutStream => monthOutController.stream; Stream get resultOutStre
Stream.of(int[])返回 Stream ,而 Stream.of(String[])返回 Stream . 为什么这两种方法的行为不同?两者都应该返回 Stream和 Stream或 St
我正在使用 rxdart在 dart 中处理流的包。我被困在处理一个特殊的问题上。 请看一下这个虚拟代码: final userId = BehaviorSubject(); Stream getSt
我到处都找遍了,还是没弄明白。我知道你可以用流建立两个关联: 用于支持数据存储的包装器意味着作为消费者和供应商之间的抽象层 数据随着时间的推移变得可用,而不是一次全部 SIMD 代表单指令,多数据;在
考虑下面的代码: List l=new ArrayList<>(); l.add(23);l.add(45);l.add(90); Stream str=l.stream
我有一个大型主干/requirejs 应用程序,我想迁移到 webpack,最新的“webpack”:“^4.27.1”,但我遇到了一个我无法解决的错误。 我一直在阅读 https://webpack
我正在使用 xmpp 开发聊天应用程序,根据我们的要求,我们有三台服务器 Apache Tomcat 7、ejabbered 2.1.11 和 mysql 5.5, to run xmppbot on
我知道如何使用 Java 库,并且我可以编写一些循环来执行我需要的操作,但问题更多,为什么 scala.collection.JavaConverters 中没有任何内容或scala.collecti
我正在尝试创建一个单一的衬里,它应该计算一个非常长的文本文件中的唯一单词。独特的词例如:márya fëdorovna scarlet-liveried,...所以基本上都是非英语词。 我的问题是我的
如果我有以下情况: StreamWriter MySW = null; try { Stream MyStream = new FileStream("asdf.txt"); MySW =
有人可以帮我将以下语句转换为 Java8: 我有一个像这样的 HashMap : private Map, List>> someMap; 我想在java8中转换以下逻辑: private Strin
有人可以帮我将以下语句转换为 Java8: 我有一个像这样的 HashMap : private Map, List>> someMap; 我想在java8中转换以下逻辑: private Strin
考虑两种测试方法parallel()和sequential(): @Test public void parallel() throws Exception { System.ou
我是 NodeJS 的新手,我基本上想做的是通过 HTTP 将 .pdf 上传到我的服务器。我正在使用 POST rquest 来处理 Content-Type multipart/form-data
哪个更好:MemoryStream.WriteTo(Stream destinationStream) 或 Stream.CopyTo(Stream destinationStream)?? 我正在谈
给定一个 Stream,我想创建一个新的 Stream,其中的元素在它们之间有时间延迟。 我尝试使用 tokio_core::reactor::Timeout 和 Stream 的 and_then
我是 Kafka Streams 和 Spring Cloud Stream 的新手,但在将集成相关代码移动到属性文件方面已经阅读了有关它的好东西,因此开发人员可以主要专注于事物的业务逻辑方面。 这里
源代码看起来非常相似:pump , pipe .为什么我要使用一个而不是另一个?一个只是另一个的更好版本吗? 最佳答案 Stream.pipe 现在显然是自 0.3.x 以来的首选方法,因此尽可能尝试
我正在寻找是否有更好的方法来解决我不得不使用这些签名的困境(注意:由于 Spock 测试,T[][] 是必需的,我提供 T[][] 作为数据提供商) 我的方法签名是: public T[][] cr
我是一名优秀的程序员,十分优秀!