【问题标题】:Entry actions with Akka FSM使用 Akka FSM 的入口操作
【发布时间】:2015-09-10 13:29:49
【问题描述】:

任何具有合理复杂性的状态机都需要在进入状态时执行一些进入操作。例如,UML 状态机图为此目的有一个特殊的操作。不幸的是,我看不到如何在 Akka FSM 中对此类进入操作(或退出操作)进行建模。对转换执行操作(使用下划线输出状态)不起作用,因为进入操作旨在更改状态数据(例如,准备在新状态下操作所需的数据结构)。关于如何在 Akka FSM 中模拟进入/退出动作的任何建议?

【问题讨论】:

  • 进入/退出动作是指在actor开始之前或actor停止之后执行的动作?或者你的意思是对状态转换的副作用?我认为你的问题不够干净。
  • 状态机术语中的进入动作是进入状态时执行的功能。与 Actor 停止/启动生命周期无关。
  • 我明白了。为什么不使用goto(NewState).using(newData) 语法来更改状态数据?

标签: akka fsm akka-fsm


【解决方案1】:

如 Akka 的 FSM documentation 中所述,[在调用 initialize 之后] 将触发初始 currentState -> currentState 通知。

这样的事情应该可以工作:

onTransition {
  case InitialState -> InitialState =>
    // Do stuff
}

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,我玩了一段时间修改原始 FSM 特征以处理进入/退出。

    https://github.com/jock71/jock-akka-fsm/blob/master/src/main/scala/jok/akka/fsm/FsmMod.scala

    可以在以下位置找到使用示例:

    https://github.com/jock71/jock-akka-fsm/blob/master/src/main/scala/jok/akka/fsm/TestAkkaFsm.scala

    当在 goto 使用中指定和在入口处理程序中更改时,我不太清楚如何处理 StateData

    【讨论】:

      【解决方案3】:

      本书Akka in Action 也使用entry actions from UML。他们使用带有通配符的转换实现进入操作,并使用外部事件来更改状态(但不是状态数据)。

      有一个完整的scala example on github。 scala中的相关部分:

      onTransition {
          case _ -> WaitForRequests => {
            if (!nextStateData.pendingRequests.isEmpty) {
              // go to next state
              self ! PendingRequests
            }
          }
      

      或者翻译成java:

      onTransition(
        matchState(null, WaitForRequests.class, () -> {
          if (!nextStateData().pendingRequests.isEmpty()) {
              // go to next state
              self().tell(PendingRequests, self());
              }
          }
        })
      

      【讨论】:

        【解决方案4】:

        如果您想为某个状态添加进入或退出操作,您需要在 onTransition 上编写一些 PartialFunction。
        例如,这是您在 AkkaFSM 中为进入或退出操作建模的方式:

        onTransition {
           case _ -> StateA => /* This is an entry action for StateA. Do something here. You can send messages to actors (or self), so some state checks or setups. */
           case StateA -> _ => /* This is an exit action for StateA. Do something here. You can send messages to actors (or self), so some state post-checks or any cleanup task for the state */
        }
        

        【讨论】:

        • 该问题与此选项明确相关,并解释了为什么它不够 - 无法更改状态数据。
        • 我想我误解了你的问题,因为我认为你只是想对状态本身或参与者中的一些本地变量执行检查或操作,而不是对数据本身。即使错误,我也会留下答案,因为它回答了标题中的问题。
        猜你喜欢
        • 2014-09-26
        • 1970-01-01
        • 1970-01-01
        • 2019-02-10
        • 1970-01-01
        • 2015-08-31
        • 2017-03-13
        • 2015-10-23
        • 2013-10-06
        相关资源
        最近更新 更多