2016-09-15 58 views
0

我想避免一纸空文消息到终止演员和避免发送消息到演员检查演员的终止和避免发送消息到演员

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没有工作,最后从平发送的消息还是结束到死字母:

[INFO] [2016年9月16日00:47:46.237] [MyActorSystem-akka.actor.default-调度-4] [阿卡://MyActorSystem/user/pingActor/pongActor]消息 [com.example演员[演员:// MyActorSystem/user/pingActor/pongActor#524615423]并非 已发送。演员[演员:// MyActorSystem/user/pingActor#1697177867]演员[PingActor $ PingMessage] 演员[akka: [1]遇到了死信。此日志记录可以关闭 或使用配置设置'akka.log-dead-letters' 和'akka.log-dead-letters-during-shutdown'进行调整。

回答

1

基于演员的异步性质,我不认为你可以在ActorSelection上转达。我想,一旦你收到Terminated消息,你肯定这个演员已经死了。但是,当演员死亡时,等待处理的邮箱中可能仍有少量消息。你可以做的是让另一位演员在DeadLetter频道上收听,如果该演员收到一条本来应该转给其他演员的消息,则采取行动。

0

到@hveiga答案另一种选择是:

如果只您收到pongActor乓后发送下一个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不会被处理莳萝您收到PongMessage pongActor

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