我想讓演員在啓動時發送消息並稍後收到回覆。在動作者啓動時使用真實(非臨時)發送者ActorRef發送消息?
從preStart
發送郵件導致臨時sender
引用(因爲該Actor尚未啓動?)。所以答覆可能是一封死信。
任何提示將不勝感激。道歉,如果我的前提是誤解 - 我是阿卡新手。
我想讓演員在啓動時發送消息並稍後收到回覆。在動作者啓動時使用真實(非臨時)發送者ActorRef發送消息?
從preStart
發送郵件導致臨時sender
引用(因爲該Actor尚未啓動?)。所以答覆可能是一封死信。
任何提示將不勝感激。道歉,如果我的前提是誤解 - 我是阿卡新手。
一種方法是在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
}
你的前提是確實不正確的是:當啓動前運行的演員已經全面開工,這是self
參考永遠不是臨時的。雖然沒有代碼,但它不可能幫助你。
發件人應始終被視爲「臨時」 - 比照。這篇博客文章,例如:
規則是簡單地被另一個線程執行的可能,比如 計劃任務,未來的 代碼塊從未關過發件人方法。關鍵是要抓住當前發件人 在VAL,如下圖所示...
- Closing Over An Akka Actor Sender In The Receive
讓發件人的副本,再後來,當你準備回覆,回覆actorRef的副本,而不是「發件人」。
您可以向您的演員發送初始消息,這會觸發發送啓動消息。或者,讓你的演員有狀態;它的啓動狀態會發送消息,然後它會轉換到運行狀態,在那裏它會收到響應。 –
Thanks @BobDalgleish - 這是否需要'preStart'中的'成爲(接收)'調用? –