简体   繁体   English

从GraphStage内部关闭Akka流(Akka 2.4.2)

[英]Closing an Akka stream from inside a GraphStage (Akka 2.4.2)

In Akka Stream 2.4.2, PushStage has been deprecated. 在Akka Stream 2.4.2中,不推荐使用PushStage。 For Streams 2.0.3 I was using the solution from this answer: 对于Streams 2.0.3,我使用的是这个答案的解决方案:

How does one close an Akka stream? 如何关闭Akka流?

which was: 这是:

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)
      }
    }

How would I close a stream in 2.4.2 immediately, from inside a GraphStage / onPush() ? 如何从GraphStage / onPush()内部立即关闭2.4.2中的流?

Use something like this: 使用这样的东西:

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)
    })
  }
}

It is more verbose but one the one side one can define this logic in a reusable way and on the other side one no longer has to worry about differences between the stream elements because the GraphStage can be handled in the same way as a flow would be handled: 它更冗长,但是一方可以以可重用的方式定义此逻辑,另一方面不再需要担心流元素之间的差异,因为GraphStage可以像流一样处理。处理:

val flow: Flow[Tpe] = ???
val newFlow = flow.via(closeStage)

Posting for other people's reference. 张贴供其他人参考。 sschaef's answer is correct procedurally, but the connections was kept open for a minute and eventually would time out and throw a "no activity" exception, closing the connection. sschaef的答案在程序上是正确的,但连接保持打开一分钟,最终会超时并抛出“无活动”异常,关闭连接。

In reading the docs further, I noticed that the connection was closed when all upstreams flows completed. 在进一步阅读文档时,我注意到当所有上游流程完成时,连接已关闭。 In my case, I had more than one upstream. 在我的情况下,我有不止一个上游。

For my particular use case, the fix was to add eagerComplete=true to close stream as soon as any (rather than all) upstream completes. 对于我的特定用例,修复是在任何(而不是全部)上游完成时立即将eagerComplete = true添加到关闭流。 Something like: 就像是:

... = builder.add(Merge[MyObj](3,eagerComplete = true))

Hope this helps someone. 希望这有助于某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM