Scala is easily my favorite programming language. It manages seamlessly to integrate a rich object-oriented paradigm with most (if not all) of the features one would expect from a functional language. Today, I started learning about Akka, which is (as described by its website), “a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and Scala.”
Inspired by Erlang’s actor-based concurrency, Akka solves many of the problems associated with multithreaded programming on the JVM. For a very brief example of how Akka works, let’s consider the scenario of a counter that we want to be able to increment and decrement in a parallel environment.
First, let’s go ahead and import Akka and create an ActorSystem for our application:
import akka.actor._
val system = ActorSystem("counterDemo")
Second, we declare a companion object to our soon-to-be Counter actor, which holds the messages we’ll be able to send.
object Counter {
case object Increment
case object Decrement
case object Print
}
With that in place, we can now declare our Counter actor:
class Counter extends Actor {
import Counter._
var count = 0
def receive: Receive = {
case Increment => count += 1
case Decrement => count -= 1
case Print => println(s"[counter] My current count is $count")
}
}
Notice that the Counter class extends from akka.actor.Actor and imports the messages from the companion object. Then, the class declares a mutable piece of state data, i.e., the count. Finally, the class implements the required method receive. The receive method is actually a partial function from Any to Unit, which specifies what the actor should do when a particular message is received.
To use our new counter application, we can import the messages from the companion object into scope. Next, we register the counter actor with the actor system previously declared. Then, using the ! infix method (read: “tell”), we can tell the actor to increment five times, decrement three times, and print the count.
import Counter._ val counter = system.actorOf(Props[Counter], "myCounter") (1 to 5).foreach(_ => counter ! Increment) (1 to 3).foreach(_ => counter ! Decrement) counter ! Print
After running this application, the following is printed to the console, as expected:
[counter] My current count is 2
This is a very interesting way of thinking about programming. Instead of calling methods on objects, we are sending messages to actors. The question I have now, though, is how are we sure we will get 2 every time in the above example? Said differently, how are we sure the Print message is executed last, given that messages are sent asynchronously? I will soon find out as I continue to learn about this impressive framework.
[UPDATE] Well, I have learned that Akka guarantees that if message A is sent before message B, message A will, indeed, be processed first. The way this works — with a pool of threads — is quite fascinating. In any event, please check out the gist below, which implements a simple voting system in Scala with Akka to demonstrate how we can change an actor’s behavior.