Непонимание Акка становится/небезупречным

Следующий код:

class HotSwapActor extends Actor {
  import context._
  def angry: PartialFunction[Any, Unit] = {
    case "foo" => sender ! "I am already angry!"
    case "bar" => become(happy)
  }

  def happy: PartialFunction[Any, Unit] = {
    case "bar" => sender ! "I am already happy :-)"; unbecome
    case "foo" => become(angry)
  }

  def receive = {
    case "foo" => become(angry)
    case "bar" => become(happy)
  }
}

class OtherActor extends Actor {
  val system = ActorSystem()
  val actor = system.actorOf(Props[HotSwapActor])
  def receive = {
    case "start" =>
      actor ! "foo"
      actor ! "bar"
      actor ! "bar"
      actor ! "foo"
    case a @ _ => println(a)
  }
}

object HotSwapMain extends App {
  val system = ActorSystem()
  val actor = system.actorOf(Props[OtherActor])
  actor ! "start"
}

Имеет выход:

Я уже счастлив: -)

Но не может быть

Я уже счастлив:-) Я уже злюсь!

Или мне не хватает семантики unbecome в unbecome в случае bar счастливой PartialFunction?

Ответы

Ответ 1

Вот как проходит поток.

  • Msg "foo" отправлено → receive получает сообщение. angry становится функцией приема. Любое следующее сообщение будет отправлено на angry
  • Msg "bar" отправлено → angry получает сообщение. happy становится функцией приема. Любое следующее сообщение будет отправлено на happy
  • Msg "bar" отправлено → happy получает сообщение. Он ответил на сообщение I am already happy :-). И тогда это unbecomes. По api для всех предыдущих вызовов context.become для параметра discardOld установлено значение по умолчанию значение true. Теперь, заменив себя, нет ничего, что могло бы стать следующим приемником. Он принимает значение по умолчанию: я receive в качестве приемника

  • Msg "foo" отправлено → receive получает сообщение. angry становится функцией приема. Любое следующее сообщение будет отправлено на angry

Ответ 2

становится необязательным вторым параметром 'discardOld'. По умолчанию это верно. Чтобы стек не поддерживался. Если вы хотите сохранить стек и получить результат как "Я уже счастлив:-) Я уже злюсь!", Передайте аргумент discardOld = false для вашей функции стать.