У меня есть актер Akka FSM, который использует SetTimer на неопределенный срок. Несколько раз я видел, что таймер не отправляет сообщение. Кто-нибудь видел такое поведение или какие-либо ошибки, которых мне следует избегать при использовании FSM?
Вот некоторая информация о том, как работает мой код.
У меня есть Akka FSM, который ожидает поступления файлов. по приезду разбираю их и храню в памяти. У меня есть таймер, который вызывается каждый час и отправляет себе сообщение PushTODB. Когда FSM получает это сообщение, он переходит в состояние неполучения и начинает работать с pushTODB. когда pushTODB завершается успешно, я получаю сообщение от актера DAL (который работает с базой данных), и FSM возвращается в состояние приема. Так что все упирается в то, что я получаю периодические сообщения PushTODB.
Любая помощь или идея приветствуются. Спасибо Манас
Добавление кода, чтобы помочь понять вопрос. Код немного изменен, чтобы скрыть некоторые детали, которые не важны для этого обсуждения, но после заглушки неважной функции код выглядит так.
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 вообще не появлялся.
Надеюсь, этот код поможет понять проблему.
..Манас