Tonight I decided to dig back into my tiny little MUD sample (which doesn’t have much in common with a real MUD at this point… but that will change soon) and upgrade it to work with the current milestone of Akka, 2.0-M3 which came out just last week from what I can tell.

There is actually quite a bit of difference in complexity and power between Akka 1.3 and Akka 2.0. There’s a detailed blog post here that covers some details on the breaking changes between 1.2/1.3 and 2.0.

The biggest thing that concerns me is that Akka 2.0 has this concept of an actor system, which is really a tree-like hierarchy of actors. Some actors act in a supervisory capacity over other child actors and this tree is query able at runtime. If this sounds like Erlang’s supervisor process system to you that’s no accident… the philosophy guiding the development of Akka 2.0’s actor system is very Erlang-ish.

So when I create my top-level Game singleton object, I now need to create an instance of an Actor System and fire up a top level actor (I can have multiple top-level actors):

package com.kotancode.scalamud

import akka.actor._
import akka.routing._

/*
 * Root-level Game singleton
 * Creates the Akka Actor System for all subsequent game objects
 */
object Game extends App {
	val system = ActorSystem("ScalaMUD")
	val server = system.actorOf(Props(new GameServer()), "server")
	println("System Starting")
	server ! ServerStart()
}

Note here the use of system.actorOf. If I want to create a subordinate (child) actor within the context of the parent actor doing the creation, then I would use context.actorOf. I can give each of my actors a unique name so that they have descriptive path names when they appear in the actor system tree.

So far I was happy with the upgrade and I didn’t have too much trouble. Then I got to the point where I was creating anonymous actors in order to execute my while loops for accepting sockets and reading input from a socket in the background… Akka 2.0 has removed the spawn { } syntax and replaced it with some severe limitations, namely you can no longer create anonymous actors that do not implement a receive method. This means the old spawn { // do something } construct is impossible, replaced with this snippet from my GameServer class:

case s:ServerStart => {
	context.actorOf(Props(new Actor {
		def receive = {
			case ss:ServerStart => {
				startSocketListener
			}
		}
	})) ! s

If you’re thinking OMGWTFBBQ at this point, you’re not alone. Basically what I’m doing is creating an anonymous actor, defining a receive method that receives a specific message and does something in response to that message and then sending a message to my anonymous actor. This is actually the way the documentation tells you to spawn off asynchronous background tasks without using named actors.

Before you start the flame war here – it is worth taking a minute to think hard about the fact that everything that occurs asynchronously within Akka is supposed to be an asynchronous event-driven, message-passing construct. In short, if I was really anal about this, I would have spawned off an actor that reads from the input socket stream in its own private loop and I would have spawned off another actor that encapsulates the output writer. When the input reader has read a line, it should send a message indicating that a line has been read and when something needs to send text to a player, it should do so through its output writer actor.

At this point I’m not that anal and I don’t need that level of complexity, so I’m leaving it out. I only mention this alternative to ease the pain of the new way of doing anonymous actors.

In short, I did get the MUD running on Akka 2.0-M3 and, while a little put off by the anonymous actor syntax, I understand its need and I applaud the type safe people for forcing actors to receive messages.

If you want to follow the code for the MUD as I continue working on it, check out my GitHub repo.