0
votes

In the Akka documentation (https://doc.akka.io/docs/akka/current/actors.html), I found the following recommended practice using Props but could not understand why doing it the other way would be "unsafe" (see the code snippet below with the comment // Props(new DemoActor(42)) would not be safe.

Question: Why "not retain a reference to its enclosing scope" is preferred and violating this could lead to problems?

Below is from Akka documentation.

Recommended Practices: 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. This also avoids the pitfalls associated with using the Props.apply(...) method which takes a by-name argument, since within a companion object the given code block will not retain a reference to its enclosing scope:

object DemoActor {
  /**
   * Create Props for an actor of this type.
   *
   * @param magicNumber The magic number to be passed to this actor’s constructor.
   * @return a Props for creating this actor, which can then be further configured
   *         (e.g. calling `.withDispatcher()` on it)
   */
  def props(magicNumber: Int): Props = Props(new DemoActor(magicNumber))
}

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

class SomeOtherActor extends Actor {
  // Props(new DemoActor(42)) would not be safe
  context.actorOf(DemoActor.props(42), "demo")
  // ...
}

The explanation offered by Akka documentation is

This method is not recommended to be used within another actor because it encourages to close over the enclosing scope, resulting in non-serializable Props and possibly race conditions (breaking the actor encapsulation).

// NOT RECOMMENDED within another actor:
// encourages to close over enclosing class
val props7 = Props(new MyActor)

But I still do not feel understand it perfectly as why it results in non-serializable Props and possibly race conditions...

1

1 Answers

0
votes

As suggested by @chunjef the question has been asked and answered in this post: What does "to close over the enclosing scope/class" mean?