我正在尝试实施akka流过滤器流程,该流程收集有关已处理数据的统计信息并实现生成的统计信息。
class SFilter[A](p: A => Boolean) extends GraphStage[FlowShape[A, A]] {
val in = Inlet[A]("SFilter.in")
val out = Outlet[A]("SFilter.out")
val shape = FlowShape.of(in, out)
override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
new GraphStageLogic(shape) {
var positive: Long = 0
var negative: Long = 0
setHandler(in, new InHandler {
override def onPush(): Unit = {
val elem = grab(in)
if (p(elem)) {
push(out, elem)
positive += 1
} else {
pull(in)
negative += 1
}
}
})
setHandler(out, new OutHandler {
override def onPull(): Unit = {
pull(in)
}
})
}
}
到目前为止一切顺利,但我希望我的SFilter[A]
属于Flow[A,A,(Long,Long)]
类型。如何在共同点结束时实现(positive,negative)
?
答案 0 :(得分:0)
您无法实现Tuple2[Long, Long]
,因为这些Longs将取决于正在运行的流本身。但是,您可以实现Future[Tuple2[Long, Long]]
,然后在流完成时完成。{/ p>
编辑:您希望以不同的方式命名自定义阶段,以便区分普通过滤器和SFilter。
答案 1 :(得分:0)
感谢Viktor Klang的建议,我能够实施以下解决方案:
class SFilter[A](p: A => Boolean) extends GraphStageWithMaterializedValue[FlowShape[A,A],Future[(Long,Long)]] {
val in = Inlet[A]("SFilter.in")
val out = Outlet[A]("SFilter.out")
val shape = FlowShape.of(in, out)
override def createLogicAndMaterializedValue(inheritedAttributes: Attributes) = {
val result = Promise[(Long,Long)]()
val logic = new GraphStageLogic(shape) {
var positive: Long = 0
var negative: Long = 0
setHandler(in, new InHandler {
override def onPush(): Unit = {
val elem = grab(in)
if (p(elem)) {
push(out, elem)
positive += 1
} else {
pull(in)
negative += 1
}
}
override def onUpstreamFinish(): Unit = {
result.success( (positive,negative) )
completeStage()
}
})
setHandler(out, new OutHandler {
override def onPull(): Unit = {
pull(in)
}
})
(logic, result.future)
}
}