Coxer
Coxer

Reputation: 1704

Misunderstanding Akka become/unbecome

The following code:

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"
}

Has the output:

I am already happy :-)

But souldn't it be

I am already happy :-) I am already angry!

Or am I missing the semantic of unbecome in unbecome in the bar case of the happy PartialFunction?

Upvotes: 20

Views: 5923

Answers (2)

user1512621
user1512621

Reputation: 67

become takes an optional second parameter 'discardOld'. By default this is true. So that the stack will not be maintained. If you want the stack to be maintained, and get the result as - "I am already happy :-) I am already angry!", pass the argument discardOld=false to your become function.

Upvotes: 3

Jatin
Jatin

Reputation: 31724

This is how is the flow.

  1. Msg "foo" sent --> receive receives the message. angry becomes the receive function. Any next message will be sent to angry
  2. Msg "bar" sent --> angry receives message. happy becomes the receive function. Any next message will be sent to happy
  3. Msg "bar" sent --> happy receives message. It replied I am already happy :-) message. And then it unbecomes. As per api for all the previous calls to context.become, the discardOld was set as default to true. Now after replacing itself there is nothing left to become the next receiver. It takes the default one i.e. receive as the receiver

  4. Msg "foo" sent --> receive receives the message. angry becomes the receive function. Any next message will be sent to angry

Upvotes: 28

Related Questions