父母在发送消息后停止时,从父母演员到儿童演员的消息上的死信

时间:2014-09-09 08:01:26

标签: akka actor

考虑下面的代码示例(版本1)。这里父actor(ActorA)向子actor(ActorB)发送消息然后停止self。由于父母演员的自我停止,在高负荷下,儿童演员甚至在从邮箱挑选消息之前就死了,因此消息变成了“死信”。 (参见下面的示例输出1)。

出于某种原因,我无法修改应用程序设计以删除父actor的自动停止。

版本1

import akka.actor.Actor
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Stop
import akka.actor.Props
import akka.actor.ActorSystem

object AkkaTest extends App {

  val system = ActorSystem("AkkaTest")

  for (i <- 1 to 5) {
    system.actorOf(Props[ActorA]) ! i  
  }

}

class ActorA extends Actor {

  def receive = {
    case i: Int => { 
      context.actorOf(Props[ActorB]) ! i
      context.stop(self)
    }
  }

  override def postStop = println("ActorA - stopped")

}

class ActorB extends Actor {

  def receive = {
    case i: Int => {
      println("ActorB - processing msg - " + i)
    }
  }

  override def postStop = println("ActorB - stopped")

}

示例输出1

ActorB - processing msg - 2
ActorB - processing msg - 1
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - processing msg - 3
ActorB - stopped
ActorA - stopped
ActorA - stopped
[INFO] [09/09/2014 08:26:56.101] [AkkaTest-akka.actor.default-dispatcher-6] [akka://AkkaTest/user/$e/$a] Message [java.lang.Integer] from Actor[akka://AkkaTest/user/$e#-289783076] to Actor[akka://AkkaTest/user/$e/$a#-86921027] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [09/09/2014 08:26:56.101] [AkkaTest-akka.actor.default-dispatcher-3] [akka://AkkaTest/user/$d/$a] Message [java.lang.Integer] from Actor[akka://AkkaTest/user/$d#-1255514179] to Actor[akka://AkkaTest/user/$d/$a#402128903] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
ActorA - stopped
ActorA - stopped
ActorA - stopped

现在考虑以下代码修改(版本2)。通过从儿童演员向父演员引入消息确认,然后在收到此确认后自动停止父演员,摆脱死信(参见示例输出2)。

第2版

import akka.actor.Actor
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.Stop
import akka.actor.Props
import akka.actor.ActorSystem

object AkkaTest extends App {

  val system = ActorSystem("AkkaTest")

  for (i <- 1 to 5) {
    system.actorOf(Props[ActorA]) ! i  
  }

}

class ActorA extends Actor {

  def receive = {
    case i: Int => context.actorOf(Props[ActorB]) ! i
    case m: MsgAck => context.stop(self) 
  }

  override def postStop = println("ActorA - stopped")

}

class ActorB extends Actor {

  def receive = {
    case i: Int => {
      sender ! MsgAck()
      println("ActorB - processing msg - " + i)
    }
  }

  override def postStop = println("ActorB - stopped")

}

case class MsgAck()

样本输出2

ActorB - processing msg - 4
ActorB - processing msg - 2
ActorB - processing msg - 5
ActorB - processing msg - 3
ActorB - processing msg - 1
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorB - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped
ActorA - stopped

现在我的问题是,还有其他方法可以达到同样的目的吗?我的意思是摆脱死信。

1 个答案:

答案 0 :(得分:1)

当父母停止时,其所有孩子都将被停止。这导致死信。确保没有死信的唯一方法是确保父母活着,直到孩子收到消息。除了ack消息之外,我无法想到任何其他方式。