设为首页 加入收藏

TOP

Akka(7): FSM:通过状态变化来转换运算行为(二)
2017-10-09 14:06:32 】 浏览:4160
Tags:Akka FSM 通过 状态 变化 转换 运算 行为
g又调用了processEvent:

  private def processMsg(value: Any, source: AnyRef): Unit = { val event = Event(value, currentState.stateData) processEvent(event, source) } private[akka] def processEvent(event: Event, source: AnyRef): Unit = { val stateFunc = stateFunctions(currentState.stateName) val nextState = if (stateFunc isDefinedAt event) { stateFunc(event) } else { // handleEventDefault ensures that this is always defined
      handleEvent(event) } applyState(nextState) }

在processEvent里的stateFunction是个Map,以stateName为主键存放StateFunction:

 /* * State definitions */
  private val stateFunctions = mutable.Map[S, StateFunction]()

而StateFuction是:

 type StateFunction = scala.PartialFunction[Event, State]

FSM的receive函数在收到消息后把消息包嵌入新构建的Event然后在processEvent里通过stateName取出相应的StateFunction后传入Event产生新的状态State。用户提供的StateFunction是通过FSM的when函数压进stateFunction Map里的:

  /** * Insert a new StateFunction at the end of the processing chain for the * given state. If the stateTimeout parameter is set, entering this state * without a differing explicit timeout setting will trigger a StateTimeout * event; the same is true when using #stay. * * @param stateName designator for the state * @param stateTimeout default state timeout for this state * @param stateFunction partial function describing response to input */ final def when(stateName: S, stateTimeout: FiniteDuration = null)(stateFunction: StateFunction): Unit = register(stateName, stateFunction, Option(stateTimeout)) private def register(name: S, function: StateFunction, timeout: Timeout): Unit = { if (stateFunctions contains name) { stateFunctions(name) = stateFunctions(name) orElse function stateTimeouts(name) = timeout orElse stateTimeouts(name) } else { stateFunctions(name) = function stateTimeouts(name) = timeout } }

我们看到when调用了register在stateFunction Map中按stateName放置StateFunction。FSM的这个stateFunction Map解决了become/unbecome产生的堆栈问题。FSM有个比较规范的结构,拿上面例子的FeelingSeasons结构做个示范:

class FillSeasons extends FSM[Seasons,SeasonInfo] with ActorLogging { import FillSeasons._ startWith(Spring,SeasonInfo(0,1))  //起始状态
  when(Spring) {   //状态在春季
    case Event(HowYouFeel,seasonInfo) => ... } when(Summer) { //夏季状态
    case Event(HowYouFeel,_) => } when(Fall) { //秋季状态
    case Event(HowYouFeel,SeasonInfo(tks,mnth)) => } when(Winter) { //冬季状态
    case Event(HowYouFeel,si@ SeasonInfo(tks,_)) => } whenUnhandled { //所有状态未处理的Event
    case Event(NextMonth,seasonInfo) => } onTransition { case Spring -> Summer => log.info("Season changed from Spring to Summer month 1") case Summer -> Fall => log.info("Season changed from Summer to Fall month 1") case Fall -> Winter => log.info("Season changed from Fall to Winter month 1") case Winter -> Spring => log.info("Season changed from Winter to Spring month 1") } initialize() //设定起始状态
 }

基本上是按照各状态定义事件处理函数StateFunction的。也可以包括状态转换处理函数TransitionHandler:

  type TransitionHandler = PartialFunction[(S, S), Unit]

最后,initialize()确定起始状态是否安排正确:

  /** * Verify existence of initial state and setup timers. This should be the * last call within the constructor, or [[akka.actor.Actor#preStart]] and * [[akka.actor.Actor#postRestart]] * * An initial `currentState -> currentState` notification will be triggered by calling this method. * * @see [[#startWith]] */ final def initialize(): Unit =
    if (currentState != null)
首页 上一页 1 2 3 4 5 6 下一页 尾页 2/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Akka(6): become/unbecome:运.. 下一篇spark获取时间

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目