Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 尝试为自定义有状态实现提取GraphStageLogic,然后将其作为参数传递给GraphStage是一个异常_Scala_Exception_Akka_Akka Stream - Fatal编程技术网

Scala 尝试为自定义有状态实现提取GraphStageLogic,然后将其作为参数传递给GraphStage是一个异常

Scala 尝试为自定义有状态实现提取GraphStageLogic,然后将其作为参数传递给GraphStage是一个异常,scala,exception,akka,akka-stream,Scala,Exception,Akka,Akka Stream,下面是简化的代码段,其中GraphStateLogic实现作为构造函数参数传递给GraphStage:- package akka.shapes.examples.notworking import akka.actor.ActorSystem import akka.stream._ import akka.stream.scaladsl.{GraphDSL, RunnableGraph, Sink, Source} import akka.stream.stage.{GraphStage,

下面是简化的代码段,其中GraphStateLogic实现作为构造函数参数传递给GraphStage:-

package akka.shapes.examples.notworking

import akka.actor.ActorSystem
import akka.stream._
import akka.stream.scaladsl.{GraphDSL, RunnableGraph, Sink, Source}
import akka.stream.stage.{GraphStage, GraphStageLogic, InHandler}

//This is base graph stage, where GraphStageLogic and SinkShape are passed in constructor parameter
class BaseGraphStage[T](val shape: SinkShape[T], graphStageLogic: GraphStageLogic) extends GraphStage[ SinkShape[T] ] {

  override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = graphStageLogic
}

//this is a sample stateful extension of GraphStageLogic, that accepts first ten elements only
class CountLogic(sinkShape: SinkShape[Int], maxValue: Int) extends GraphStageLogic(sinkShape) {
  var counter: Long = 0

  override def preStart(): Unit = {
    pull(sinkShape.in)
  }

  setHandler(sinkShape.in, new InHandler {
    override def onPush(): Unit = {
      val e = grab(sinkShape.in)
      println("conditional sink : " + e)
      counter = counter + 1
      counter == maxValue match {
        case true => completeStage()
        case false => pull(sinkShape.in)
      }
    }
  })
}


object SampleSinkNotWorking {

  def main(args: Array[String]): Unit = {
    implicit val actorSystem = ActorSystem("NotWroking")
    implicit val actorMaterializer = ActorMaterializer()

    val inlet = Inlet[Int](name = "sampleInlet")
    val sinkShape = SinkShape( inlet )
    val countGraphStateLogic = new CountLogic(sinkShape, 10)

    val sinkGraphStage = new BaseGraphStage[Int](sinkShape, countGraphStateLogic)
    val sink = Sink.fromGraph( sinkGraphStage )

    val graph = GraphDSL.create() { implicit builder =>

      import GraphDSL.Implicits._

      Source(1 to 100) ~> sink

      ClosedShape
    }

    val runnableGraph = RunnableGraph.fromGraph(graph)

    runnableGraph.run()
  }
}
运行上述代码会导致ArrayIndexOutOfBoundsException:-

线程“main”java.lang.ArrayIndexOutOfBoundsException中的异常: -1在akka.stream.stage.GraphStageLogic.setHandler(GraphStage.scala:439)在 akka.shapes.examples.notworking.CountLogic.(SampleSinkNotWorking.scala:24) 在 akka.shapes.examples.notworking.SampleSinkNotWorking$.main(SampleSinkNotWorking.scala:46) 在 akka.shapes.examples.notworking.SampleSinkNotWorking.main(SampleSinkNotWorking.scala)

我试过调试,看起来入口id是-1,但没有重置


但是,当GraphStateLogic作为构造函数参数传递给GraphState时,为什么它没有被重置呢?

我正在重构您的代码,问题已经解决,请看:


类BaseGraphStage(maxValue:Int)扩展了GraphStage[SinkShape[Int]]{
val入口=入口[Int](name=“sampleInlet”)
重写def createLogic(继承的属性:属性):GraphStageLogic=
带有分段图的新GraphStageLogic(shape){
变量计数器:Int=0
设置处理器(入口,新入口处理器{
覆盖def onPush():单位={
val e=抓斗(入口)
日志信息(s“$e已消耗”)
计数器+=1
如果(计数器==最大值){
完成测试()
}否则{
牵引(入口)
}
}
})
覆盖def preStart():单位=
牵引(入口)
覆盖def postStop():单位=
计数器=0
}
覆盖def形状:SinkShape[Int]=SinkShape(入口)
}
对象示例SinkNotWorking{
def main(参数:数组[字符串]):单位={
隐式val actorSystem=actorSystem(“不工作”)
隐式val-actorMaterializer=actorMaterializer()
val sink=sink.fromGraph(新BaseGraphStage(10))
源(1到100)。运行时使用(接收器)
}
}

我不能完全回答您的最后一个问题,但我认为所有的技巧都是在graph阶段的上下文中创建入口,而不是从中创建入口,并使用pre和post处理程序。希望这能有所帮助。

我正在重构您的代码,问题已经解决,请看:


类BaseGraphStage(maxValue:Int)扩展了GraphStage[SinkShape[Int]]{
val入口=入口[Int](name=“sampleInlet”)
重写def createLogic(继承的属性:属性):GraphStageLogic=
带有分段图的新GraphStageLogic(shape){
变量计数器:Int=0
设置处理器(入口,新入口处理器{
覆盖def onPush():单位={
val e=抓斗(入口)
日志信息(s“$e已消耗”)
计数器+=1
如果(计数器==最大值){
完成测试()
}否则{
牵引(入口)
}
}
})
覆盖def preStart():单位=
牵引(入口)
覆盖def postStop():单位=
计数器=0
}
覆盖def形状:SinkShape[Int]=SinkShape(入口)
}
对象示例SinkNotWorking{
def main(参数:数组[字符串]):单位={
隐式val actorSystem=actorSystem(“不工作”)
隐式val-actorMaterializer=actorMaterializer()
val sink=sink.fromGraph(新BaseGraphStage(10))
源(1到100)。运行时使用(接收器)
}
}
我不能完全回答您的最后一个问题,但我认为所有的技巧都是在graph阶段的上下文中创建入口,而不是从中创建入口,并使用pre和post处理程序。希望有帮助