Search code examples
scalaactorakka

How to restrict actor messages to specific types?


In Akka, is there a way to restrict messages to actors to be of a specific static type other than using the "Typed Actor" APIs that use an RPC style programming model?

Can I use the message passing style with Akka without throwing away static type safety at the actor boundaries?

For example, I'd like to use code like this:

sealed abstract class FooMessage
case object Foo extends FooMessage
case object Bar extends FooMessage

class FooActor extends Actor[FooMessage] {
  def receive = {
    case Foo => () // OK

    // Would raise a compiler error:
    // case s: String => error("Can't happen, String is not a subtype of FooMessage") 

  }
}

val fooActor = actorOf[FooActor]
fooActor ! Foo // OK

// Won't compile:
fooActor ! "Hello"

Perhaps one would have to extend some base trait or have a construct like Either to allow for system level messages (Exit, etc.).


Solution

  • Then you'd have to encode the message type into the Actor ref, which would drastically decrease the value of something like the ActorRegistry.

    Also, with powerful mechanics like "become" (which is fundamental to the actor model) typing the messages is less valuable.

    Since Akka doesn't leak memory when a message is not matched to the current behavior, there is not the same risk of sending the "wrong" messages to the "wrong" actor.

    Also, Actors are by nature dynamic, so if you want to make them static, use TypedActor (which is not RPC, it's just as RPC as regular actors, void methods are ! calls, Future return type is !!! and other return types are based on !!)

    The common practice is to declare what messages an Actor can receive in the companion object of the Actor, which makes it very much easier to know what it can receive.

    Does that help?