Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

  • ambiguous as to the number of actors it points to, and
  • has some overhead that's undesirable for many tells

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.

like image 591
Arne Claassen Avatar asked Jun 30 '15 20:06

Arne Claassen


People also ask

Is Akka asynchronous?

Akka actors are asynchronous from the beginning. Reactive programs can be implemented in either way, synchronous and asynchronous.

Which method provides initial Behaviour to actor?

Start Hook This method is called when the actor is first created.

Are Akka actors single threaded?

Behind the scenes Akka will run sets of actors on sets of real threads, where typically many actors share one thread, and subsequent invocations of one actor may end up being processed on different threads.

How do I create a new actor in Akka?

In Akka you can't create an instance of an Actor using the new keyword. Instead, you create Actor instances using a factory spawn methods. Spawn does not return an actor instance, but a reference, akka. actor.


1 Answers

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.

like image 75
Ryan Avatar answered Oct 02 '22 19:10

Ryan