在Akka Stream 2.4.2中,不推荐使用PushStage。对于Streams 2.0.3,我使用的是这个答案的解决方案:
How does one close an Akka stream?
是:
import akka.stream.stage._
val closeStage = new PushStage[Tpe, Tpe] {
override def onPush(elem: Tpe, ctx: Context[Tpe]) = elem match {
case elem if shouldCloseStream ⇒
// println("stream closed")
ctx.finish()
case elem ⇒
ctx.push(elem)
}
}
如何从GraphStage / onPush()中立即关闭2.4.2中的流?
答案 0 :(得分:3)
使用类似的东西:
val closeStage = new GraphStage[FlowShape[Tpe, Tpe]] {
val in = Inlet[Tpe]("closeStage.in")
val out = Outlet[Tpe]("closeStage.out")
override val shape = FlowShape.of(in, out)
override def createLogic(inheritedAttributes: Attributes) = new GraphStageLogic(shape) {
setHandler(in, new InHandler {
override def onPush() = grab(in) match {
case elem if shouldCloseStream ⇒
// println("stream closed")
completeStage()
case msg ⇒
push(out, msg)
}
})
setHandler(out, new OutHandler {
override def onPull() = pull(in)
})
}
}
它更冗长,但是一方可以以可重用的方式定义此逻辑,另一方面不再需要担心流元素之间的差异,因为GraphStage
可以在与处理流程的方式相同:
val flow: Flow[Tpe] = ???
val newFlow = flow.via(closeStage)
答案 1 :(得分:1)
发布给其他人的参考资料。 sschaef的答案在程序上是正确的,但连接保持打开一分钟,最终会超时并且没有活动#34;例外,关闭连接。
在进一步阅读文档时,我注意到当所有上游流程完成时,连接已关闭。就我而言,我有不止一个上游。
对于我的特定用例,修复是在任何(而不是全部)上游完成后立即将eagerComplete = true添加到关闭流。类似的东西:
... = builder.add(Merge[MyObj](3,eagerComplete = true))
希望这有助于某人。