maks
maks

Reputation: 6006

Does actor state have to be serializable?

class MyActor(val service1: MyService1, val service2: MyService2) extends Actor {
  ...
}

I plan to use my actor behind the router in the cluster via akka-cluster extension. Some parent actor will create "pool" of these actors. So, creation of this "pool" will look similar to:

context.actorOf(Props(classOf[MyActor], service1, service2), "myActor")

and in the configuration file in deployment section I'll specify router options for this actor.

But I guess that to get it work MyService1 and MyService2 have to be serializable, don't they? Perhaps this requirement relates not directly to actor but for its Props?

Upvotes: 0

Views: 292

Answers (1)

Diego Martinoia
Diego Martinoia

Reputation: 4662

If you have tried out playing a little with the cluster-sharding extension (which builds on the top of clustering), you realize that, when you are creating remote actors, you are kind of forfeiting the degree to which you control their creation. So, in general, if you want props, you need them to be serializable.

If you want to see if your actors/props/messages are serializable, you can go in the config of akka and enable these two flags (more info here):

akka {
  actor {
    serialize-messages = on
    serialize-creators = on
  }
}

I'd rather suggest to you a different approach tough, one that will work even if you have to use cluster-sharding (where you cannot have arguments in actor constructors): Initialize via message.

Your actors would become something like:

class MyActor extends Actor {
  var service1: Option[MyService1] = None
  var service2: Option[MyService2] = None

  override def receive = {
    case Init(s1, s2) => service1 = Some(s1); service2 = Some(s2)
  }
}

Note that, in this scenario, unless you are persisting your actors via event sourcing or snapshot, you'll need to re-send the init message on startup of the actor (when it dies and starts again or when it's moved to another machine). But usually you do use persistance and it's not a big deal. You can also add a message queue in your actor to hold all the "action" messages received before you get the init message, and then serve them once you have received your init message.

Upvotes: 1

Related Questions