akka - Constructor vs. preStart: when to use which?
问题描述
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?
解决方案
从通过构造函数初始化的文档中:
使用构造函数进行初始化有很多好处。首先,它可以使用
val
字段来存储在 Actor 实例生命周期内不会改变的任何状态,从而使 Actor 的实现更加健壮。构造函数在创建actor实例时调用actorOf
并且在重新启动时调用,因此actor的内部总是可以假设发生了正确的初始化。
从通过 preStart 初始化的文档中:
Actor的方法
preStart()
仅在第一个实例的初始化期间直接调用一次,即在其创建时ActorRef
。在重新启动的情况下,preStart()
从 调用postRestart()
,因此如果没有被覆盖,preStart()
则在每次重新启动时调用。但是,通过覆盖postRestart()
可以禁用此行为,并确保只有一次调用preStart()
.此模式的一个有用用法是
ActorRefs
在重新启动期间禁用为子项创建新的。这可以通过覆盖来实现preRestart()
。
如果您希望在每次实例化 Actor 时都进行初始化(包括重新启动:在重新启动时,会创建底层 Actor 的新实例),请通过构造函数使用初始化。示例场景是每当创建一个actor时使用不变状态。
如果您希望仅在创建 Actor 的第一个实例时进行初始化,请使用初始化 viapreStart
和 overridepostRestart
以不调用preStart
。示例用例是在重新启动时保留子角色(默认情况下,preRestart
停止角色的子角色,这就是文档提到preRestart
此示例用例的覆盖的原因)。
推荐阅读
- firebase - 如何从 Firebase 存储中获取图像 URL?
- wordpress - 'core/colums' innerBlocks 允许的块
- c++ - 'float' 和 'const c' 类型的无效操作数
- assembly - 如何实现 vpmovmskb 对 ZMM 寄存器的影响?
- r - 从具有 S4 元素的列表中提取值
- mysql - MySql GROUP_CONCAT 函数,语法正确
- c++ - 如何调用函数在C中抛出一个指针数组
- mongodb - Mongodb 使用 $lookup 聚合运算符加入多文档并使用 $or 一次在加入的文档中搜索
- php - 如何记录服务器对php代码的处理?如何反编译php代码?
- database - 有没有办法在 cassandra 中插入 json/maps 列表?