2017-08-08 14 views
0

我想讓演員在啓動時發送消息並稍後收到回覆。在動作者啓動時使用真實(非臨時)發送者ActorRef發送消息?

preStart發送郵件導致臨時sender引用(因爲該Actor尚未啓動?)。所以答覆可能是一封死信。

任何提示將不勝感激。道歉,如果我的前提是誤解 - 我是阿卡新手。

+0

您可以向您的演員發送初始消息,這會觸發發送啓動消息。或者,讓你的演員有狀態;它的啓動狀態會發送消息,然後它會轉換到運行狀態,在那裏它會收到響應。 –

+0

Thanks @BobDalgleish - 這是否需要'preStart'中的'成爲(接收)'調用? –

回答

2

一種方法是在preStart將消息發送到self

class MyActor extends Actor { 

    def preStart(): Unit = { 
    self ! CallService 
    } 

    def receive = { 
    case CallService => 
     (service ? ServiceRequest).mapTo[ServiceResponse].pipeTo(self) 
    case ServiceResponse => 
     // do something with the response 
    } 
} 

在本answer所描述的,如果你想在演員它所處理的所有其他消息之前發送郵件,那麼你可以stash其他消息:

class MyActor extends Actor with Stash { 

    def preStart(): Unit = { 
    self ! CallService 
    } 

    def uninitialized: Receive = { 
    case CallService => 
     (service ? ServiceRequest).mapTo[ServiceResponse].pipeTo(self) 
     unstashAll() 
     context.become(initialized) 
    case _ => stash() // if we get a message other than CallService, stash it 
    } 

    def initialized: Receive = { 
    case ServiceResponse => 
     // do something with the response from the service 
    case ... 
    } 

    def receive = uninitialized 
} 
1

你的前提是確實不正確的是:當啓動前運行的演員已經全面開工,這是self參考永遠不是臨時的。雖然沒有代碼,但它不可能幫助你。

0

發件人應始終被視爲「臨時」 - 比照。這篇博客文章,例如:

規則是簡單地被另一個線程執行的可能,比如 計劃任務,未來的 代碼塊從未關過發件人方法。關鍵是要抓住當前發件人 在VAL,如下圖所示...

- Closing Over An Akka Actor Sender In The Receive

讓發件人的副本,再後來,當你準備回覆,回覆actorRef的副本,而不是「發件人」。

相關問題