Arne Claassen
Arne Claassen

Reputation: 14404

Asynchronous Initialization of Akka Actors

I'm trying to find the proper pattern for initializing an actor asynchronously, so that I can look up dependent ActorRefs it needs. I want to avoid using ActorSelection, since it's

Looking at the Actor LifeCycle it seems to be all pretty much synchronous until the message loop starts, including preStart, etc., which leads me to think that I have only one of two choices:

Use a factory method with a signature of Future[ActorRef]

All dependencies for constructing the actor are resolved asynchronously and passed in via Props.

The main problem with this approach is that you cannot use this factory to construct an actor inside of another actor, since it then has the same problem, i.e. it's turtles all the way down, wiring up the hierarchy of all actors and their dependencies asynchronously.

Use become and stash to transition the actor

The actor is created with actorOf, immediately resulting in an ActorRef but it starts in an Initialization state, does it's dependency resolution, stashing incoming messages in the meantime, and finally becomeing the Running state and unstashAlling.

This feels a lot more idiomatic for actors, even though my dependencies will all be var instead of val.

Both seem like a lot of overhead, making me wondering if I these are the best options or if I just haven't found the proper pattern in the docs.

Upvotes: 10

Views: 809

Answers (1)

Ryan
Ryan

Reputation: 7247

There's no reason your dependencies have to be vars when using become:

val initializing: Actor.Receive = {
  case Dependencies(d1, d2) => context.become(working(d1, d2))
}

def working(d1: Dependency, d2: Dependency): Actor.Receive = {
  case msg => d1.fetch(...) // whatever
}

def receive = initializing

Also, actorFor is a) deprecated and b) doesn't create an actor.

Upvotes: 8

Related Questions