Hamy
Hamy

Reputation: 21592

Confusion over Akka Actors vs Java Objects

I'm trying to familiarize myself with Akka and Actors in general, but I think I'm missing a point. My receive loops are becoming overly large. For example:

class Node extends Actor {
  def receive {
    case "pause" => pause
    case "resume" => resume
    case "methodX" => methodX
    case "methodY" => methodY
    case "methodZ" => methodZ
  } 
}

I'm new to Actors, Scala, and functional programming. I think my experience in object-land is leaking into my actor definitions, so my question is looking for guidance on how to define an Actor's API the 'right' way and avoid this untyped message explosion.

Upvotes: 0

Views: 739

Answers (1)

Björn Antonsson
Björn Antonsson

Reputation: 1019

How many messages all depend on what you are trying to encapsulate. A good rule is to try to keep the actor focused to one task, and then have it delegate things to other actors (thereby making the interface small). Also making the actors stateless and having the state in the message you send around will help a lot.

It is important to keep the messages immutable, but that doesn't mean that they have to be strings. You can define the messages that you accept, and send with case classes (to get immutability), and let the compiler do some checking for you if you make them extend a sealed trait. Here's an example where the compiler will complain that your match is non exhaustive since you don't handle the FooMessage in the receive.

object MyActor {
  // these are the messages we accept
  sealed abstract trait Message
  case class FooMessage(foo: String) extends Message
  case class BarMessage(bar: Int) extends Message

  // these are the replies we send
  sealed abstract trait Reply
  case class BazMessage(foo: String) extends Reply
}

class MyActor extends Actor {
  import MyActor._
  def receive = {
    case message: Message ⇒ message match {
      case BarMessage(bar) => sender ! BazMessage("Got " + bar)
    }
  }
}

You should also try to think about actors in a fire and do something else in the meantime way (fire and forget sounds to harsh). That is you should use tell (!) and not ask (?). Don't think about message sending as method calls. That will make your code block and not scale.

One common example of actor usage is to have a chain of actors where each actor does one task and then forwards the transformed message to the next actor. In the end you reply to the actor that initiated the chain, or whoever he said you should reply to, thereby shortcutting all actors in the middle. No need for the messages to travel down and then back up the chain.

Hope this gives you some ideas.

Upvotes: 1

Related Questions