2014-10-01 81 views
0

我有一個無限期使用SetTimer的Akka FSM actor。我幾次見過這個計時器沒有發送消息。有沒有人看到這種行爲或使用FSM時必須避免的任何問題?Akka FSM計時器停止發送消息

以下是關於我的代碼如何工作的一些信息。

我有一個等待文件到達的Akka FSM。抵達後我解析它們並將它們存儲在我的記憶中。我有一個計時器每小時都會被調用,並向自我發送PushTODB消息。當FSM接收到該消息時,它將進入非接收狀態,並且pushTODB工作。當pushTODB成功時,我收到來自DAL actor的消息(數據庫工作),並且FSM返回到接收狀態。因此,所有事情都是由於我收到定期的PushTODB消息。

歡迎任何幫助或想法。 謝謝 Manas

添加代碼以幫助理解問題。 的代碼位修改爲隱藏一些細節,是不是這個討論,但磕碰非重要功能後,重要的是這樣的代碼是什麼樣子

class FileMonitor extends Actor with ActorLogging 
    with LoggingFSM[Status, Data]{ 
    val config = context.system.settings.config 
    val landingZones = ConfigUtils.getLZInfoList(config) 
    val pushToDBFreq = 1 hour 
    val manager = context.actorOf(Props(new MMSIManager)) 
    manager ! Activate 
    var collection = ActorRef.noSender 
    val workingFolder = "/tmp" 
    val UOWProvCH1 = "ch1path" 
    val UOWProvCH2 = "ch2path" 

    startWith(Idle, toBeHandled(Seq(newFile(Paths.get(""))))) 
    when(Idle, inf) { 
    case Event(Activate(ref, again), list) => 
     collection = ref 
     init(again) 
     goto(Active) using list 
    } 
when(Active, inf) { 
    case Event(nf @ newFile(someFile, au, nextau), list: toBeHandled) => 
    dosomething() 
    stay 

    case Event(BeIdle, list: toBeHandled) => 
    log.info("Asking manager to pushToDB........") 
    manager ! pushToDB() 
    goto(NonTransmitting) using list 
} 
when(NonTransmitting, inf) { 
    case Event(event :pushToDBSuccess, list: toBeHandled) => 
    log.debug("received pushTODBSucess message...............") 
    cleanit(list) 
    list.fileName.foreach(file => sendPositional(file)) 
    goto(Active) using list.copy(fileName = Seq.empty) 
} 
whenUnhandled{ 
    case Event(nf :newFile, list @ toBeHandled(l)) => 
    list.copy(fileName = l :+nf) 
    stay using list 
    stay 
    case x => log.warning(s"Got message $x.........") 
    stay 
} 
onTransition { 
    case Idle -> Active => { 
     setTimer("BeIdle", BeIdle, 1 hour, true) 
     log.info("Going Active............") 
} 
} 

由於周圍的工作我檢查,如果計時器積極並重新創建它;但我很想知道是否有什麼我在這裏做錯了或丟失任何東西,因爲定時器不會派遣BeIdle消息。有時它會運行幾個小時,然後BeIdle停止顯示,至少在一個實例中,BeIdle完全沒有顯示出來。

希望這段代碼有助於理解問題。

..Manas

+0

你可以發佈你的代碼嗎? – Ryan 2014-10-01 19:36:24

回答

0

一個腥的事情是,你開始從空閒到活動的每一個轉變的新的計時器。

考慮在退出活動狀態時調用cancelTimer("BeIdle")或在preStart塊中啓動單個定時器。

+0

我的演員總是開始空閒。父母發送「激活」消息。父母也是這位演員的主管,以防​​萬一我的演員崩潰監督員會重新啓動它。目前我正在檢查定時器是否存在,如果沒有;我正在創建一個新的計時器。我不清楚如果我的演員崩潰會發生什麼;計時器是否會崩潰或停留?瑪納斯 – Manas 2014-10-13 17:22:19