A ‘Ping Pong’ Scala Akka actors example

Akka actors FAQ: Can you share an “Akka Actors 101” example (i.e, a simple “Introduction to Akka Actors” example)?

Sure. If you’re looking for the simplest possible Akka example, check out my Akka Actors “Hello, world” tutorial. If that one is overly simplified and you want something more, continue on here.

Quick intro: When I first started to learn about Java threading, there was a nice “Ping Pong” example you could look at to get a basic idea of how threading worked. I was surprised when there wasn’t a similar tutorial for Akka actors, so I took a little time to write my own.

The SBT build file

First up, I created this as an SBT project, so here’s my build.sbt file, updated for Scala 2.10.0 and Akka 2.1.1:

name := "Akka Ping Pong Example"

version := "1.1"

scalaVersion := "2.10.0"

resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.1.1"

Source code

I’ll describe the code a little more below, but to get things rolling, here's the source code for my simple Akka actors Ping Pong example:

import akka.actor._

case object PingMessage
case object PongMessage
case object StartMessage
case object StopMessage

/**
 * An Akka Actor example written by Alvin Alexander of
 * http://alvinalexander.com
 *
 * Shared here under the terms of the Creative Commons
 * Attribution Share-Alike License: http://creativecommons.org/licenses/by-sa/2.5/
 * 
 * more akka info: http://doc.akka.io/docs/akka/snapshot/scala/actors.html
 */
class Ping(pong: ActorRef) extends Actor {
  var count = 0
  def incrementAndPrint { count += 1; println("ping") }
  def receive = {
    case StartMessage =>
        incrementAndPrint
        pong ! PingMessage
    case PongMessage => 
        incrementAndPrint
        if (count > 99) {
          sender ! StopMessage
          println("ping stopped")
          context.stop(self)
        } else {
          sender ! PingMessage
        }
  }
}

class Pong extends Actor {
  def receive = {
    case PingMessage =>
        println("  pong")
        sender ! PongMessage
    case StopMessage =>
        println("pong stopped")
        context.stop(self)
  }
}

object PingPongTest extends App {
  val system = ActorSystem("PingPongSystem")
  val pong = system.actorOf(Props[Pong], name = "pong")
  val ping = system.actorOf(Props(new Ping(pong)), name = "ping")
  // start them going
  ping ! StartMessage
}

Discussion

Here are a few quick notes about this example:

  • As you can see from the import statement, I’m using Akka actors, not the older Scala actors.
  • When you implement an Akka actor, you define the receive method, and implement your desired behavior in that method.
  • Messages between actors should be immutable, and case classes are great for this purpose.
  • The code in my PingPongTest class shows the two ways to create Akka actors (see the 'val pong' and 'val ping' lines.) I’ve written more about this in my Simple Scala Akka actors examples tutorial.
  • I get everything started by sending a StartMessage to my “ping” actor. After that, the two actors bounce messages back and forth as fast as they can until they stop.

I hope that brief discussion has been helpful. If you have any questions or improvements, just leave a note in the Comments section below.