2016-09-15 85 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在那段時間內沒有回覆,可能意味着它已經死了。而且你會得到一個沒有迴應的消息列表。因此,問責製得到了照顧。