context.become改变了Akka Actor的行为

时间:2017-07-19 21:09:00

标签: scala akka actor

我正在学习如何使用context.become来控制我的演员的状态,我使用这段代码:

class MyActor extends Actor {

  override def receive: Receive = {
     println("Happens here")
     active(Set.empty)
   }

  def active(isInSet: Set[String]): Receive = {
    case Add(key) =>
      context.become(active(isInSet+key))
    case Contains(key) =>
      sender() ! isInSet(key)
    case ShowAll =>
      println(isInSet.toSeq)
  }

}

case class Add(key: String)
case class Contains(key: String)
object ShowAll


object DemoBecome extends App{

override def main(args: Array[String]): Unit = {

 val system = ActorSystem("BecomeUnbecome")
 val act = system.actorOf(Props(classOf[MyActor]), "demoActor")

 act ! Add("1")
 act ! ShowAll
 act ! Add("2")
 act ! ShowAll

 Thread.sleep(10000)
 System.exit(0)

}

当我发送第一条消息时,"收到"工作并打印消息,在第二条消息未显示之后,这是我的输出:

Happens here
Set()
Vector(1)
Set(1)
Vector(1, 2)

如果我改变了接收方法,为此:

def receive = {
  case a: Add => println("happens here Add" )
  case c: Contains => println("happens here Contains")
  case ShowAll => println("happens here Show")
}

我收到了这个输出:

happens here Add
happens here Show
happens here Add
happens here Show

所以我试过,追踪"收到"被阻止"但是我没有成功,我的疑问是:当我在我的演员中使用context.become时,Akka如何以及何时在第一个之后处理消息?

1 个答案:

答案 0 :(得分:6)

当您使用context.become时,您正在改变演员的行为。这意味着,当actor使用默认的receive行为启动它时。但是,当它收到消息时,它会打印消息Happens here并使用部分函数active来处理它。

因为,在active内你调用context.become(active(_)),行为者的行为会发生变化。从现在开始,当消息被发送到actor时,它将执行部分函数active而不是receive方法,这就是为什么你在输出中没有多次看到Happens here的原因