This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 13.11, “How to switch between different Akka Actor states with become
”.
Problem
In a Scala application, uou want a simple mechanism to allow an Akka actor to switch between the different states it can be in at different times.
Solution
Use the Akka “become” approach. To do this, first define the different possible states the actor can be in. Then, in the actor’s receive
method, switch between the different states based on the messages it receives.
The following example shows how the actor named DavidBanner
might switch between its normalState
and its angryState
(when he becomes The Hulk):
package actortests.becometest import akka.actor._ case object ActNormalMessage case object TryToFindSolution case object BadGuysMakeMeAngry class DavidBanner extends Actor { import context._ def angryState: Receive = { case ActNormalMessage => println("Phew, I'm back to being David.") become(normalState) } def normalState: Receive = { case TryToFindSolution => println("Looking for solution to my problem ...") case BadGuysMakeMeAngry => println("I'm getting angry...") become(angryState) } def receive = { case BadGuysMakeMeAngry => become(angryState) case ActNormalMessage => become(normalState) } } object BecomeHulkExample extends App { val system = ActorSystem("BecomeHulkExample") val davidBanner = system.actorOf(Props[DavidBanner], name = "DavidBanner") davidBanner ! ActNormalMessage // init to normalState davidBanner ! TryToFindSolution davidBanner ! BadGuysMakeMeAngry Thread.sleep(1000) davidBanner ! ActNormalMessage system.shutdown }
Here’s a description of the code:
- The
davidBanner
actor instance is created as shown in previous recipes. - The
davidBanner
instance is sent theActNormalMessage
to set an initial state. - After sending
davidBanner
aTryToFindSolution
message, it sends aBadGuysMakeMeAngry
message. - When
davidBanner
receives theBadGuysMakeMeAngry
message, it usesbecome
to switch to theangryState
. - In the
angryState
the only messagedavidBanner
can process is theActNormalMessage
. (In the real world, er, entertainment world, it should be programmed to receive other messages, likeSmashThings
.) - When
davidBanner
receives the finalActNormalMessage
, it switches back to thenormalState
, again using thebecome
method.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |
Discussion
As shown, the general recipe for using the become
approach to switch between different possible states is:
- Define the different possible states, such as the
normalState
andangryState
. - Define the
receive
method in the actor to switch to the different states based on the messages it can receive. As shown in the example, this is handled with amatch
expression.
It’s important to note that the different states can only receive the messages they’re programmed for, and those messages can be different in the different states. For instance, the normalState
responds to the messages TryToFindSolution
and BadGuysMakeMeAngry
, but the angryState
can only respond to the ActNormalMessage
.