2012-11-08 38 views
0

我有以下代碼遍歷人員列表,並在class1中爲每個人員調用回調。當演員完成時,Akka跟蹤

def syncPeople(callback: Person => _) = Future { 
    person.findAll(criteria).foldLeft(0L) { (count, obj) => 
     callback(obj) 
     count + 1 
    } 
} 

回調和調用syncPeople是Class2中,看起來與此類似

def getActor(person: Person):ActorRef = { 
    if(person.isMale) maleActor 
    else femaleActor 
} 

def process(person: Person): Unit = { 
    val workActor = getActor(person) 
    workActor ! person 
} //The actor does the actual work and may be quite intense 

def syncPeople(process) 

現在,我要跟蹤同步所有的人所花費的總時間。即最後一名工作者完成工作時。我正在使用第三個Actor:MonitorActor來跟蹤開始和結束時間。當他們處理個人時,MaleActor,FemaleActor可以發送消息到

跟蹤這些衍生過程的最佳方式是什麼?

我探索

  1. Future.sequence //但該類發送workActor的消息是不是一個演員。所以未來不會收到消息

  2. 當他們完成時跟蹤personIds,但沒有使用var,在MonitorActor中累積收到的消息它不可能實現此操作,並且使用var不是首選的方法事情

有什麼能實現這個

回答

4

滑稽的其他方式,我工作在一個非常類似的問題,這在時刻。我建議的解決方案是使用akka-fsm跟蹤狀態。

基本上在你的狀態對象之外的東西,這樣做產生長期代表一個id:

def getId(): Long = System.currentTimeMillis()/1000L 

當正確實施的狀態對象是不變的,所以你只要保持整個交易重用這個ID 。

我知道這個答案缺少很多的實現細節,但我仍然在自己的代碼中自己在實現自己的實現。希望在閱讀akka-fsm後稍微閱讀一下,這個答案會有意義嗎?

+0

感謝您的指針,我結束了使用akka-fsm ..它有如一個單一的請求syncPeople()時的魅力。爲了處理對syncPeople的多個請求,我最終爲每個請求創建了一個FSM actor的實例,並在syncPeople完成時停止它。不知道這是否正確的做法。我沒有最終使用getId()。你能否詳細說明使用Id的方法。 – scout

1

不要妖魔化可變狀態,它是SHARED可變狀態,這會導致大多數問題。您在演員內部沒有共享的可變狀態,因爲您始終與演員參與者交談並且演員一次只處理一條消息(沒有競爭條件和其他邪惡內容)。我說的是,可以使用var(除非你在演員中產生了一些期貨,這會改變var,因爲這樣你就回到了SHARING可變狀態)。 FSM是@devnulled提出的另一個解決方案,但它聽起來更像是一個矯枉過正的用例。