我认为这种对 OTP 主管行为的自定义并不容易。OTP 主管的设计方式迫使我遵循一些严格的设计实践。在这种情况下,最重要的一点是主管除了监视其子代并在异常终止的情况下重新启动它们之外,不应该做任何其他事情。监督者中不应有额外的逻辑,以免在监督者中引入任何错误,这是监督树和容错的关键部分。
当孩子死亡时,我想以与崩溃前相同的状态重新启动它
- 这通常是不好的做法,因为孩子可能因为终止前的损坏状态而死亡,并在这种情况下以相同的状态重新启动它肯定会出问题
在这种情况下有什么标准方法吗?
在重新启动它们之前,在主管中自定义子项的状态,这违反了主管的良好设计实践。因此,这类任务通常以不同的方式完成,例如通过引入另一个进程,例如 gen_server,该进程将负责通过主管 (supervisor:start_child) 启动子进程并维护所有进程的监视器。这个额外的过程可以在开始新的孩子之前做任何需要的定制。
如何使用 OTP 获取终止进程的 Pid?
- 在通过 supervisor:start_child 启动子进程的附加过程中,您可以监视它们,然后收听 DOWN 消息。例如,在 gen_server 的情况下,您将使用 handle_info 函数,如下所示:
handle_info({'DOWN', Ref, process, _Pid, _}, S) ->
handle_down_worker(Ref, _Pid, S).
或者也许可以在终止之前获取孩子的状态,然后将孩子恢复到崩溃前的相同状态?
- 如果我错了,请纠正我,但我认为在 Erlang 中不可能与“DOWN”消息一起发送子进程在终止之前的状态。如果这可能,那么我可以只处理类似于 {DOWN, Pid, Reason, State} 的消息并以相同的状态或部分状态重新启动进程。但是,我在想.. 你怎么能保持突然死亡的孩子的状态,例如被 exit(Pid, kill) 杀死?我怀疑这是可能的。