Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor vs. preStart: when to use which?

Tags:

akka

In Akka you can initialize the actor's state within the constructor. Furthermore, as part of the actor's lifecycle, the preStart method can be overridden to initialize the actor's state and will be called:

  • when the actor is first started, before it starts processing its first message
  • when the actor is restarted, unless postRestart is overridden to not call it

The two ways (constructor and preStart) seem to cover overlapping phases of the actor's startup phase, with the slight difference that the constructor is guaranteed to be called upon restart, whereas preStart can be skipped, provided that you override postRestart.

Are there recognized or documented best practices or patterns regarding which one to use in which case?

like image 365
stefanobaghino Avatar asked Jul 26 '18 12:07

stefanobaghino


1 Answers

From the documentation on initialization via constructor:

Using the constructor for initialization has various benefits. First of all, it makes it possible to use val fields to store any state that does not change during the life of the actor instance, making the implementation of the actor more robust. The constructor is invoked when an actor instance is created calling actorOf and also on restart, therefore the internals of the actor can always assume that proper initialization happened.

From the documentation on initialization via preStart:

The method preStart() of an actor is only called once directly during the initialization of the first instance, that is, at creation of its ActorRef. In the case of restarts, preStart() is called from postRestart(), therefore if not overridden, preStart() is called on every restart. However, by overriding postRestart() one can disable this behavior, and ensure that there is only one call to preStart().

One useful usage of this pattern is to disable creation of new ActorRefs for children during restarts. This can be achieved by overriding preRestart().

If you want initialization to occur every time an actor is instantiated (which includes restarts: on a restart, a new instance of the underlying actor is created), use initialization via constructor. The example scenario for this is the use of invariant state whenever an actor is created.

If you want initialization to occur only when the first instance of an actor is created, use initialization via preStart and override postRestart to not call preStart. The example use case for this is the preservation of child actors across restarts (by default, preRestart stops an actor's children, which is why the documentation mentions overriding preRestart for this example use case).

like image 141
Jeffrey Chung Avatar answered Oct 18 '22 02:10

Jeffrey Chung