【问题标题】:Check actor's termination and avoid sending message to that actor检查演员的终止并避免向该演员发送消息
【发布时间】:2017-01-24 01:24:34
【问题描述】:

我想避免向已终止的演员发送死信消息,并避免向该演员发送消息

class PingActor extends Actor with ActorLogging {
  import PingActor._

  var counter = 0
  var sendMessages = true
  val pongActor = context.actorOf(PongActor.props, "pongActor")
  context.watch(pongActor)

  def receive = {
    case Terminated(pong) =>
      sendMessages = false


    case Initialize =>
        println("In PingActor - starting ping-pong")
      pongActor ! PingMessage("ping")
    case PongActor.PongMessage(text) =>
      println("In PingActor - received message: {}", text)
      counter += 1
      if (counter == 10 ) context.system.shutdown()
      else {
        context.actorSelection(pongActor.path) ! PingMessage("ping")
      }
  } 
}
class PongActor extends Actor with ActorLogging {
  import PongActor._
  var counter = 0

  def receive = {
    case PingActor.PingMessage(text) => 
      println(s"In PongActor - received message: $text counter = $counter \n reply with pong message")

      if (counter < 5) {
        counter = counter + 1
      }
      else
        {
          println("Oh crap , bye bye ")
          context.stop(self)
        }
      sender() ! PongMessage("pong")

  }

actorSelection 没有像我预期的那样工作,并且从 ping 发送的最后一条消息仍然以死信结束:

[信息] [09/16/2016 00:47:46.237] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/pingActor/pongActor] 消息 [com.example.PingActor$PingMessage] 来自 演员[akka://MyActorSystem/user/pingActor#1697177867] 到 Actor[akka://MyActorSystem/user/pingActor/pongActor#524615423] 不是 发表。 [1] 遇到死信。这个日志记录可以转 关闭或使用配置设置“akka.log-dead-letters”进行调整 和'akka.log-dead-letters-during-shutdown'。

【问题讨论】:

    标签: scala akka


    【解决方案1】:

    基于演员的异步性质,我认为您不能为此转发ActorSelection。我认为一旦您收到Terminated 消息,您就可以确定演员已经死了。但是,当参与者死亡时,邮箱中可能仍有少量消息等待处理。您可以做的是让另一个演员在DeadLetter 频道上监听,并在该演员收到本应发送给其他演员的消息时采取行动。

    【讨论】:

      【解决方案2】:

      @hveiga 答案的另一种选择可能是:

      仅在收到来自 pongActor 的 pong 后才发送下一条 ping 消息。这样您就可以控制是否应该发送它们。但是,如果负载很高,那将是一个高瓶颈。

      var buffer = 0;
      def receive = {
          case Terminated(pong) =>
            sendMessages = false
      
          case Initialize =>
            if(buffer == 0){
                self ! SendMsg
                buffer = buffer+1;
             } else buffer = buffer +1;
          case SendMsg => 
                println("In PingActor - starting ping-pong")
                pongActor ! PingMessage("ping")
      
          case PongActor.PongMessage(text) =>
               buffer = buffer -1;
               if(buffer > 1) self ! SendMsg
               .....
        } 
      

      除了手动处理之外,您还可以stash 他们。这样后续的Initialize 就不会在您从 pongActor 收到PongMessage 的时候得到处理

      更好的设计可能是:每隔 5 秒左右不断发送消息并检查响应。如果 PongActor 在这段时间内没有回复,可能意味着它已经死了。你会得到一个没有回应的消息列表。因此,问责制得到了照顾。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-09
        • 2014-12-02
        • 1970-01-01
        • 2014-07-10
        • 1970-01-01
        相关资源
        最近更新 更多