Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Misunderstanding Akka become/unbecome

Tags:

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?

like image 345
Coxer Avatar asked Feb 10 '14 11:02

Coxer


1 Answers

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

like image 152
Jatin Avatar answered Oct 16 '22 17:10

Jatin