为什么在 GenServer 中启动主管会导致进程重启行为出现问题?

Why does starting a Supervisor in a GenServer cause problems with process restart behavior?

如问题标题所述:

Why does starting a Supervisor in a GenServer cause problems with process restart behavior?

我找到了一个讨论 here,其中陈述了以下内容:

Specifically:

  • "There is less guarantee provided by the supervision tree as the process might exit and the supervisor will not have terminated its children."

  • "This can lead to problems if the supervisors children are named because the named children might still exist when a restart occurs higher up the tree (above the process calling start_link in its init/1"

  • "you lose some advanced OTP features, like code reloading, as process modules are discovered by walking the supervision tree"

根本原因是什么?这在一般情况下是否成立?

参考资料

  1. Related code changes
  2. Github issue

OTP(监督树)建立在 BEAM 功能之上,例如监控、链接、信号和捕获它们。

主管是 gen_servers 他们自己,唯一的目的是 monitoring/restarting 他们的 children 并以标准方式终止 them/dying。如果您创建了一个 gen_server 来产生主管,则意味着您处于该级别,而普通主管没有晋级。

让我们考虑一下这个 OTP 场景:

         P1 - Parent supervisor
         |
         G1 - GenServer
         |
         S1 - Children supervisor
         |
         C1 - Children worker

如果你有一个 gen_server 作为主管 (G1) 在其 children (S1) 已经终止,parent 可能会重新启动 gen_server (G1')。这个会生成 S1',而 S1' 又会生成 C1'。

突然有多个S1和C1实例同时运行,这很可能是个问题

关于提到的代码重新加载问题,这意味着code_changed回调树触发器将停止在G1(因为G1不会将其传播到S1),而不是代码不会加载。

TL;DR: 主管非常专业gen_servers。如果你把一个正则 gen_server 放在监督树的中间,而不提供监督者提供的所有保证,你就会失去该子树中的一些 OTP 特性。