2015-06-20 41 views
0

目前,我有收到一些消息,並保存該消息的內容可變類級別的變量的演員:應該避免Akka Actor中的可變狀態嗎?

class MyActor extends Actor { 

    val items1: Seq[Item] = _ 
    val items2: Seq[Item] = _ 

    def receive = { 
     case Start(items1, items2) => 
     items1= items1 
     items2 = items2 

     case Result(...) => ... 
    } 

    private def method1(args...) = { 
     // do something with items1 and items2 
    } 

    private def method2(args...) = { 
     // do something with items1 and items2 
    } 

} 

和我讀到它真的好創建多個receive功能和使用context.become/unbecome處理不同的州。 所以在我的情況下,我可以用receive功能如下:

def running(items1: Seq[Item], items2: Seq[Item]): Receive = { 
     case Result(...) => ... 
    } 

    val waiting: Receive = { 
     case Start(items1, items2) => 
      context.become(running(items1, items2)) 
      start() 
    } 

這種做法在我看來很清晰,美觀大方,但問題是,我有其他的方法(method1method2),它需要這個items1items2變量。我認爲唯一可能的解決方法是將items1items2作爲函數傳遞給method1method2,但此方法已經有2-3個參數,並且向它們添加更多參數會使它們難以閱讀(實際上我有2個以上的參數方法)。

那麼,在這種情況下Akka是否有任何模式?或者,在課堂級別var(就像我的第一個例子)那樣,這很「合法」?

+0

調用'method1'和'method2'的方法或時間? –

回答

5
So, is there any patterns in Akka for such cases? 

我不知道任何。

Or it's pretty 'legal' to have class-level vars (as in my first example)? 

它是確定有var裏面的演員,只要你不從閉合或期貨訪問它們。

但是,我建議你去參數解決方案。如果你的參數列表變得很長,你可以考慮把它們分組在case class es。

3

擁有類級別的可變狀態絕對可以 - 但只要您確保它不是從receive以外的其他線程訪問的。

Eamples這樣的「異類」的線程:

  • 創建訪問的可變狀態的封閉並將它傳遞給另一個演員。
  • 從這位演員的接收方法啓動一個新線程 - 使用Akka調度程序或任何其他方式。

總之,不從演員內推出新的線程,不通過關閉給其他演員,你會沒事的。