Akka 终止一个挥舞的阿克卡演员

Akka 终止一个挥舞的阿克卡演员,akka,Akka,我有下面的演员设置,使用Akka演员(2.10) A-繁殖->B-繁殖->C A-发送作业->B-发送作业->C C-发送结果->A(重复) 然而,在某个时刻,A注意到它应该更改发送给B/C的工作负载,因为C正在发送大量的消息,而这些消息最终证明是无用的。然而,在这种情况下,C的收件箱似乎很满,和/或C可能被阻止 A如何告诉B立即关闭C?丢失B和C的状态和消息是可以接受的,因此销毁它们并生成新消息是一种选择。如果参与者按照您描述的方式启动,那么以正确的方式使用停止将满足您的要求。根据文件,呼叫s

我有下面的演员设置,使用Akka演员(2.10)

A-繁殖->B-繁殖->C

A-发送作业->B-发送作业->C

C-发送结果->A(重复)

然而,在某个时刻,A注意到它应该更改发送给B/C的工作负载,因为C正在发送大量的消息,而这些消息最终证明是无用的。然而,在这种情况下,C的收件箱似乎很满,和/或C可能被阻止


A如何告诉B立即关闭C?丢失B和C的状态和消息是可以接受的,因此销毁它们并生成新消息是一种选择。

如果参与者按照您描述的方式启动,那么以正确的方式使用
停止将满足您的要求。根据文件,呼叫stop将同时:

1) 阻止其他邮件进入邮箱(发送至死信)

2) 获取邮箱的当前内容,并将其发送到死信(虽然这是基于邮箱impl,但重点是它们不会被处理)

现在,如果参与者需要在完全停止之前完成当前正在处理的消息,那么如果消息被“卡住”,停止(或其他相关内容)将无法解决问题,但我认为这不是您描述的情况

我将一个小代码示例放在一起演示。基本上,A会向B发送一条消息,开始向C发送工作。B会向C发送一些工作,C会将该工作的结果发送回A。当A收到一定数量的响应时,它会通过停止B触发B和C的停止。当B完全停止时,它会再次重新启动进程,总次数最多为2次,因为它会自动停止。代码如下所示:

case object StartWork
case class DoWork(i:Int, a:ActorRef)
case class WorkResults(i:Int)

class ActorA extends Actor{
  import context._
  var responseCount = 0
  var restarts = 0

  def receive = startingWork

  def startingWork:Receive = {
    case sw @ StartWork =>
      val myb = actorOf(Props[ActorB])
      myb ! sw      
      become(waitingForResponses(myb))
  }

  def waitingForResponses(myb:ActorRef):Receive = {
    case WorkResults(i) =>
      println(s"Got back work results: $i")
      responseCount += 1
      if (responseCount > 200){
        println("Got too many responses, terminating children and starting again")
        watch(myb)
        stop(myb)
        become(waitingForDeath)
      }
  }

  def waitingForDeath:Receive = {
    case Terminated(ref) => 
      restarts += 1
      if (restarts <= 2){
        println("children terminated, starting work again") 
        responseCount = 0
        become(startingWork)
        self ! StartWork
      }
      else{
        println("too many restarts, stopping self")
        context.stop(self)
      }

  }
}

class ActorB extends Actor{
  import concurrent.duration._
  import context._  
  var sched:Option[Cancellable] = None

  override def postStop = {
    println("stopping b")
    sched foreach (_.cancel)
  }

  def receive = starting

  def starting:Receive = {
    case sw @ StartWork =>
      val myc = context.actorOf(Props[ActorC])
      sched = Some(context.system.scheduler.schedule(1 second, 1 second, self, "tick"))
      become(sendingWork(myc, sender))
  }

  def sendingWork(myc:ActorRef, a:ActorRef):Receive = {
    case "tick" => 
      for(j <- 1 until 1000) myc ! DoWork(j, a)

  }
}

class ActorC extends Actor{
  override def postStop = {
    println("stopping c")
  }
  def receive = {
    case DoWork(i, a) =>
      a ! WorkResults(i)      
  }
}
case对象开始工作
案例类DoWork(i:Int,a:ActorRef)
案例类工作结果(i:Int)
类ActorA扩展了Actor{
导入上下文_
var responseCount=0
var重新启动=0
def接收=启动工作
def启动工作:接收={
案例sw@StartWork=>
val myb=actorOf(Props[ActorB])
myb!sw
成为(等待响应(myb))
}
def waitingForResponses(myb:ActorRef):接收={
案例工作结果(i)=>
println(s“恢复工作结果:$i”)
响应计数+=1
如果(响应计数>200){
println(“得到太多响应,终止子项并重新开始”)
手表(myb)
停止(myb)
成为(等待死亡)
}
}
def waitingForDeath:接收={
案例终止(参考)=>
重新启动+=1
如果(重新启动)
val myc=context.actorOf(Props[ActorC])
sched=Some(context.system.scheduler.schedule(1秒,1秒,self,“勾选”))
成为(发送工作(myc,发送人))
}
def发送工作(myc:ActorRef,a:ActorRef):接收={
案例“勾号”=>
对于(j)
a!工作成果(一)
}
}
它的边缘有点粗糙,但它应该表明一点,从B到C级联停止将阻止C向a发送响应,即使它的邮箱中仍然有邮件。我希望这是您正在寻找的