How do i do classic actor become and unbecome in typed actor

Viewed 103

I am building an implementation and I would like to switch around behaviours. How do I switch between three behaviours and back? My issues is that I do not know the right way to change the behaviour and then change it back to the main behaviour after processing that message. I have tried this


    def answerMachine: Behavior[Message] = Behaviors.setup{ context: ActorContext[Message] =>
    Behaviors.receiveMessage{
      case s@Behave =>
        println("Am told to behave: changing like chameleon")
        EchoMachine(s, Behaviors.same)
      case Back() =>
        println("Now am back")
        Behaviors.same
    }
  }


def EchoMachine(firstMsg: Message, behav:  Behavior[Message]): Behavior[Message] = Behaviors.setup{ context: ActorContext[Message] =>
    Behaviors.receiveMessage {
      case Back() =>
        println("I have changed to EchoMachine..")
        behav
      case Behave =>
        println("I am behaving oo")
        behav
    }
  }


val system = ActorSystem(TypedConvo.answerMachine, "Machine")

system.ref ! Behave
system.ref ! Back()

By the time I sent Back() I expected answerMachine to be the one that get the message but it was EchoMachine even after changing behavior.

Thanks.

1 Answers

There is no become in typed actors because a new behaviour is returned every time. In effect become is called every time a message is processed, and that is how state is maintained. So the answer to how to "switch between three behaviours" is simply to return which ever behaviour is required at the time.

The problem with the sample code is that returning Behaviours.same means "don't change the behaviour". So setting behav to Behaviours.same means that EchoMachine returns Behaviours.same which keeps the behaviour as EchoMachine rather than going back to answerMachine.

Try setting behav to answerMachine:

Behaviors.receiveMessage{
  case s@Behave =>
    println("Am told to behave: changing like chameleon")
    EchoMachine(s, answerMachine)
  case Back() =>
    println("Now am back")
    Behaviors.same
}

Now the EchoMachine will return answerMachine as the new behaviour once the message is processed. Of course if EchoMachine always reverts to answerMachine it can just return answerMachine.

Related