Scala Akka Cheatsheet

Featured

A quick wrap-up from the hello-akka example of Typesafe Inc. (http://typesafe.com/activator/template/hello-akka) so nobody has to weed thru the docs to remember the syntax after being over to the Java/C++ world for a while.

One Actor is no Actor. Actors come in systems.

Carl Hewitt , inventor of the Actor Model

Agenda

  • Create Message classes that are exchanged between Actors.
  • Define an Actor by defining a receive routine.
  • Create an ActorSystem and ask it to create an Actor for us
  • Send messages to the Actor and examine the response with the help of the Inbox.

Define messages as case objects and classes

To remember:

  • Messages must be immutable and should be Serializable (for remoting).
  • Scala’s case classes come in handy because the compiler does a lot of plumbing (http://www.scala-lang.org/old/node/107)
case object Greet
case class WhoToGreet(who: String)
case class Greeting(message: String)

Define an Actor

  • An actor usually has state.
  • Inherits from Actor base class.

Basic Pattern

def receive = { case M1 => ...; case M2 => ... }
class Greeter extends Actor {
 var greeting = ""

 def receive = {
   // Sophisticated Actors will usually use pattern matching
   case WhoToGreet(who) => greeting = s"hello, $who"
   case Greet           => sender ! Greeting(greeting)
  }
 }

Create infrastructure

  • Construct an ActorSystem using the companion Object.
  • Give the ActorSystem a name.
val system = ActorSystem("helloakka")

Create an instance of your Actor

  • Use the ActorSystem’s  actorOf  method, passing Props[Greeter] and an identifying name. Greeter is the type of our Actor.
val greeter = system.actorOf(Props[Greeter], "greeter")

Send a message

  • Use the exclamation mark method (or tell) and pass a message object that is covered by the actors case statement.
  • I tend to prefer a more explicit notation.
greeter ! WhoToGreet("akka")
greeter tell WhoToGreet("akka")
greeter.tell(WhoToGreet("akka"))
  • Akka uses Scala’s implicit parameter feature (parameter derived from context) to pass the sender’s ActorRef.
  • Use the “sender” reference provided by the Actor base class to reply with a message.

Test the Actor

Inbox is a class that is kind of a non-responding Actor that is handy to trigger an Actor (that again triggers other Actors) and collect its responses.

val inbox = Inbox.create(system)
greeter tell WhoToGreet("akka")
inbox.send(greeter, Greet)
val Greeting(message) = inbox.receive(5.seconds)

assert(message == "akka")

Thoughts on Automated Testing

Depending on the complexity of the logic it may come in handy to treat the Actor as an integration component without business logic and create separate classes that do business logic. Decoding messages and responding to them seems enough responsibility for one class. Real world receive routines quickly become convoluted or the actor class gets too many method.

Object-Oriented Software Constructions and Actor Systems

You will find that the style from Object-Oriented Software Construction is an excellent basis for writing actor systems. Controlling side-effects is essential to not violating the Actor Models rules.

Note how Actors must always be in a stable state before and after they handle an incoming message. A well-constructed real-world Actor will have explicit preconditions, postconditions and invariants. In the end it is a managed, stateful object.

Disclaimer

All example code and wisdom was adapted from the hello-akka example created by Typesafe Inc. and is not my original work.

Advertisements