akka actor可以捕获所有状态中的特定消息,而无需实现相同的代码

时间:2016-10-13 11:35:42

标签: scala akka

我有一个管理不同状态的演员,例如:

case object Start 
case object Stop
case object Init

class Foo extends Actor {

 def receive: Receive = {
   case Init =>
      doSomeInit()
      context become busy 
      self ! Start
   case Stop =>
      context stop self

  }
}
 def busy: Receive = {
   case Start => 
    doingSomeProcessing()
    context become receive
   case Stop =>
      context stop self
}
}

我想避免在每个状态下编写停止处理代码(类似于FSM中的whenUnhandled) 有没有使用FSM的惯用方法呢?

1 个答案:

答案 0 :(得分:6)

使用orElse并将公共消息移动到单独的部分功能。 receivebusy是部分功能。您可以使用orElse撰写部分函数,​​如下面的代码所示。

订单很重要。因此根据用例做f1 orElse f2f2 orElse f1 f1,f2是部分函数

case object Start
  case object Stop
  case object Init

  class Foo extends Actor {

    def common: Receive = {
      case Stop =>
        context stop self
    }

    def receive: Receive = common orElse {
      case Init =>
        context become busy
        self ! Start
    }

    def busy: Receive = common orElse {
      case Start =>
        context become receive
    }
  }

Scala REPL

scala> val f: PartialFunction[Int, String] = { case 1 => "one"}
f: PartialFunction[Int, String] = <function1>
scala> val g: PartialFunction[Int, String] = { case 2 => "two"}
g: PartialFunction[Int, String] = <function1>
scala> val x = f orElse g
scala> f(1)
res9: String = "one"
scala> x(2)
res10: String = "two"
scala> x(1)
res11: String = "one"