设为首页 加入收藏

TOP

Akka(7): FSM:通过状态变化来转换运算行为(五)
2017-10-09 14:06:32 】 浏览:4159
Tags:Akka FSM 通过 状态 变化 转换 运算 行为
[S, D]
= timeout match { case f: FiniteDuration ? copy(timeout = Some(f)) case Duration.Inf ? copy(timeout = SomeMaxFiniteDuration) // we map the Infinite duration to a special marker, case _ ? copy(timeout = None) // that means "cancel stateTimeout". This marker is needed } // so we do not have to break source/binary compat. // TODO: Can be removed once we can break State#timeout signature to `Option[Duration]` /** * Send reply to sender of the current message, if available. * * @return this state transition descriptor */ def replying(replyValue: Any): State[S, D] = { copy(replies = replyValue :: replies) } /** * Modify state transition descriptor with new state data. The data will be * set when transitioning to the new state. */ def using(@deprecatedName('nextStateDate) nextStateData: D): State[S, D] = { copy(stateData = nextStateData) } ... }

FSM DSL中的transform是这样定义的:

  final class TransformHelper(func: StateFunction) { def using(andThen: PartialFunction[State, State]): StateFunction = func andThen (andThen orElse { case x ? x }) } final def transform(func: StateFunction): TransformHelper = new TransformHelper(func)

我们看到TransformHelper用using对入参func:StateFunction施用用户提供的andThen: PartialFunction[State,State]后返回新的状态State。这个using与State.using是不同的。下面是一个transform用法例子:

when(Running) { transform { case Event(m, Target(Actor.noSender)) =>
        goto(Uninitialised) using NoConfig case Event(m, Target(ref)) =>
        ref ! m stay } using targetTransformer } def targetTransformer: PartialFunction[State, State] = { case s @ State(stateName, Target(ref), _, _, _) if ref.path.name.startsWith("testActor") => log.debug("Setting target to dead letters") s.using(Target(Actor.noSender)) }

transform{...}产生的State传给了targetTransformer然后经过模式匹配拆分出properties后用s.using更新stateData。

与become/unbecome相同,我们也可以在FSM里使用stashing。下面是一个用例:

when(Uninitialised) { case Event(Config(ref), _) =>
      goto(Running) using Target(ref) case Event(_, _) => stash stay } when(Running) { case Event(m, Target(ref)) =>
      ref ! m stay } onTransition { case Uninitialised -> Running => unstashAll() }

当然,还有如stop,setTimer,replying,forMax,onTermination等方法和函数,这里就不一一详述了,有兴趣可以直接查询Akka/actor/FSM.scala。

下面是本次讨论的示范源码:

import akka.actor._ sealed trait Seasons   //States
case object Spring extends Seasons case object Summer extends Seasons case object Fall extends Seasons case object Winter extends Seasons //sealed trait SeasonData //Data
case class SeasonInfo(talks: Int, month: Int) object FillSeasons { sealed trait Messages    //功能消息
  case object HowYouFeel extends Messages case object NextMonth extends Messages def props = Props(new FillSeasons) } class FillSeasons extends FSM[Seasons,SeasonInfo] with ActorLogging { import FillSeasons._ startWith(Spring,SeasonInfo(0,1))  //起始状态
  when(Spring) {   //状态在春季
    case Event(HowYouFeel,seasonInfo) => val numtalks = seasonInfo.talks + 1 log.info(s"It's ${stateName.toString}, feel so gooood! You've asked me ${numtalks} times.") stay using seasonInfo.copy(talks = numtalks) } when(Summer) { //夏季状态
    case Event(HowYouFeel,_) => val numtalks = stateData.talks + 1 log.info(s"It's ${stateName.toString}, it's so hot! You've asked me ${numtalks} times") stay().using(stateData.copy(talks = numtalks)) } when(Fall) { //秋季状态
    case Event(HowYouFeel,SeasonInfo(tks,mnth)) => val numtalks = t
首页 上一页 2 3 4 5 6 下一页 尾页 5/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Akka(6): become/unbecome:运.. 下一篇spark获取时间

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目