2016-12-09 30 views
0

我有一個演員,可以處於多個狀態。初始狀態應該從外部傳遞:如何在演員範圍之外實現接收功能並將其傳遞給演員

class MyActor(openId: String, initialState: Receive) extends Actor { 

    val connected: (String) => Receive = (openId: String) => { 
    case AuthorizedOk(user) => context.become(authorized(user)) 
    ... 
    case message => unhandled(message) 
    } 

    val authorized: (IUserInfo) => Receive = (user: IUserInfo) => { 
    case SomeLogic => context.become(...) 
    case message => unhandled(message) 
    } 

    def receive: Actor.Receive = initialState 
} 

我需要設置初始狀態connected或構造authorized。當然它也可能是其他功能。但我不知道如何來實現這一目標:

new MyActor("id", ???) 

回答

2

我看到兩種可能性

  1. 有狀態傳遞給演員的開始前的生命週期方法

  1. 有一個對象夥伴,可用於在初始化actor實例時傳遞狀態。東西的線:

    對象MyActor {

    DEF道具(初始化狀態:YourState)= Props.actorOf(新MyActor(初始化狀態))

    }

另外,初始在你的例子中的狀態不需要是部分函數。您可以將它建模爲一個案例類,然後使用context.become在各個狀態演變時移動。

編輯:添加一個例子來更清楚一點!

sealed trait State 
case object Authorized extends State 
case object UnAuthorized extends State 

class MyActor(state: State) extends Actor { 
    def receive: Receive = { 
    case state: State => 
    // do some logic 
    val newState = someLogic(state) 
    // evolve with the new state 
    context.become(active(newState)) 
    } 

    def active(newState: State): Receive = { 
    // do the pattern matching on the state and evolve 
    } 

    override def preStart(): Unit = { 
    super.preStart() 
    // send the initial state to this actor 
    self ! state 
    } 
} 
+0

感謝您的回覆。我的問題是,我不明白(scala新手)如何在actor範圍外實現接收函數,所以我可以將它傳遞給actor。一些例子會很好! – zella

+1

你爲什麼要這麼做? Receive函數是Actor類中的一個函數,在擴展Actor時需要重寫。此外,您獲得的Actor引用僅僅是底層Actor實例的代理,因此您可能無法像在自己的示例(授權,連接)上那樣調用您的方法或字段。 – sparkr