Akka FSM Goto未来

时间:2015-04-07 10:39:00

标签: scala akka fsm

我试图在将来改变FSM状态,但我没有工作...... 我想我正在寻找pipeTo like method。

When(State.Waiting) {
   case Event(anyMsg, anyData) =>
      asyncCode.map(res =>
         if (res == 1) {
            goto(State.Working) using Data.MyData
         } else {
            stay() replying "bad response"
         }

      )
}

goto命令执行但fsm没有将状态更改为State.Working

我自己找到了这个工作

When(State.Waiting) {
   case Event(anyMsg, anyData) =>
      asyncCode.map(res =>
         if (res == 1) {
            self ! "do job"
         } else {
            stay() replying "bad response"
         }

      )
   case Event("do job", anyData) => {
      goto(State.Working) using Data.MyData
   }
}

可能有更好的解决问题的想法

2 个答案:

答案 0 :(得分:8)

不要在将来改变你的演员的状态,也不要改变主"线程"内的任何东西。 解决问题的正确方法是向self发送一条消息,这将改变状态,如

When(State.Waiting) {
  case Event(anyMsg, anyData) =>
    asyncCode.map(res =>
      if (res == 1) {
        self ! GoToWorking(Data.MyData)
      } else {
        self ! Stay
      }
    )
    goto(State.WaitingForResponse)
}

When (State.WaitingForResponse) {
  case Event(GoToWorking(data), _) =>
    goto(State.Working) using data
  case Event(Stay,_) =>
    stay()
}

答案 1 :(得分:5)

您永远不应该从异步回调中关闭并修改actor的状态(例如Future组合器)。对于FSM方法也是如此,它们对于actor是私有的。 actor应该对异步事件做出反应的唯一方法是接收消息。你的第二个代码几乎是正确的,除了你甚至不应该从回调中调用stay()。异步结果应该最终作为发送给actor的消息,然后可以改变它的状态。您可能希望引入一个新的等待状态,在启动异步调用时转换到该状态,一旦完成(actor接收结果),请转到State.Working。