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:
postRestart
is overridden to not call itThe 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?
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 callingactorOf
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 itsActorRef
. In the case of restarts,preStart()
is called frompostRestart()
, therefore if not overridden,preStart()
is called on every restart. However, by overridingpostRestart()
one can disable this behavior, and ensure that there is only one call topreStart()
.One useful usage of this pattern is to disable creation of new
ActorRefs
for children during restarts. This can be achieved by overridingpreRestart()
.
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).