Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Akka Actor Props factory

Tags:

akka

actor

Akka and I are getting to know each other.

From : Akka 2.3.6 (current) Actor Recommended Practice

These is an example actor called DemoActor :

class DemoActor(magicNumber: Int) extends Actor {
  def receive = {
    case x: Int => sender() ! (x + magicNumber)
  }
}

In Recommended Practices section of the doc it states : "It is a good idea to provide factory methods on the companion object of each Actor which help keeping the creation of suitable Props as close to the actor definition as possible." Which they do like this :

object DemoActor {
  def props(magicNumber: Int): Props = Props(new DemoActor(magicNumber))
}

Question : What is the difference between specifying the factory for props method like :

object DemoActor {
  def props(magicNumber: Int): Props = Props(classOf[DemoActor], magicNumber)
}

In case you missed it, the difference was the argument to the Props constructor :

new DemoActor(magicNumber)

VS

classOf[DemoActor], magicNumber

From the same akka documentation page a bit further up in the Props section, it also mentions when using Props(classOf[ActorWithArgs], "arg1"): "The presence of a matching constructor is verified during construction of the Props object, resulting in an IllegalArgumentEception if no or multiple matching constructors are found."

That's good, isn't it?!?....

like image 264
neurozen Avatar asked Nov 03 '14 03:11

neurozen


1 Answers

That's good, isn't it?!?....

Yes, but it is even better if the error can be caught during compile time. The advantage of invoking the constructor directly is that the compiler will catch the problem of no matching constructor instead of an exception being thrown at runtime.

An interesting thing about the Props apply method is that when you write:

Props(new DemoActor(magicNumber))

the constructor of the actor is not invoked immediately when the Props instance is created. The constructor invocation is passed by name rather than by value. You can see this in signature of the Props apply method:

def apply[T <: Actor](creator: ⇒ T)(implicit arg0: ClassTag[T]): Props

Notice the right arrow in the creator parameter. This allows the creator construction to be postponed, and potentially executed in another process for remote actors.

A potential hazard here is if the new operation closes over the scope and captures a value that is not intended to be serialized or is not serializable, thus making the Props object also not serializable. This is why the documentation recommends doing this in the companion object of the actor—to minimize the risk of closing over data that is not intended to be serialized.

like image 142
Eric Zoerner Avatar answered Jan 01 '23 09:01

Eric Zoerner