我正在使用OTP监管行为来监管和重启子进程。但是当子进程死亡时,我希望能够以它崩溃前的相同状态重新启动它。
如果我编写自己的定制监管器,我可以接收 {EXIT,Pid,Reason} 消息并采取相应措施。然而,使用OTP监管行为时,一切都由OTP管理,我没有任何控制权。我只实现了一个init回调函数。
在这种情况下有没有标准方法?如何动态自定义被otp监管者重启子进程的状态?如何使用OTP获取终止进程的Pid?或者也许可以在终止前获取子进程的状态,然后将子进程恢复到其崩溃前的相同状态?
我正在使用OTP监管行为来监管和重启子进程。但是当子进程死亡时,我希望能够以它崩溃前的相同状态重新启动它。
如果我编写自己的定制监管器,我可以接收 {EXIT,Pid,Reason} 消息并采取相应措施。然而,使用OTP监管行为时,一切都由OTP管理,我没有任何控制权。我只实现了一个init回调函数。
在这种情况下有没有标准方法?如何动态自定义被otp监管者重启子进程的状态?如何使用OTP获取终止进程的Pid?或者也许可以在终止前获取子进程的状态,然后将子进程恢复到其崩溃前的相同状态?
我认为这种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)杀死该进程?我怀疑这是不可能的。不知道你在做什么具体的事情,但我可以想象以下情况是有意义的:
因此,如果我有12个代表Cobol 12个部落的子进程,每个子进程都会使用自己的名称作为ETS表的键来查找之前的状态。每个进程在其状态更改时也会更新表(再次使用其名称作为键)。
如果一个子进程被杀死,主管将自动重新启动该子进程,并执行步骤2。步骤3将在子进程的handle_call、handle_cast和handle_info方法中处理(我对你的进程性质做了一些假设)。通过主管,还可以使用多种重启策略,甚至可以重启兄弟进程。
希望这能给你一些思路。