简体   繁体   English

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

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

As the title of the question states:正如问题的标题所说:

Why does starting a Supervisor in a GenServer cause problems with process restart behavior?为什么在 GenServer 中启动 Supervisor 会导致进程重启行为出现问题?

I found a discussion here that states the following:我在这里找到了一个讨论其中说明了以下内容:

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" “如果主管子项被命名,这可能会导致问题,因为当在树的更高位置重新启动时,命名的子项可能仍然存在(在其 init/1 中调用 start_link 的进程上方)

  • "you lose some advanced OTP features, like code reloading, as process modules are discovered by walking the supervision tree" “你失去了一些高级的 OTP 功能,比如代码重新加载,因为流程模块是通过遍历监督树来发现的”

What's the underlying reason?根本原因是什么? Does this hold true in general?这在一般情况下是否成立?

References参考

  1. Related code changes 相关代码更改
  2. Github issue Github 问题

OTP (the supervision tree) is built on top of BEAM features, such as monitoring, linking, signals and trapping them. OTP(监督树)建立在 BEAM 功能之上,例如监控、链接、信号和捕获它们。

Supervisor are gen_servers themselves, with the only purpose of monitoring/restarting their children and terminating them/dying in a standard way. Supervisor 本身就是gen_servers ,其唯一目的是监视/重新启动他们的孩子并以标准方式终止他们/死亡。 If you create a gen_server that spawns a supervisor, it means that you something in that level and that a regular supervisor did not make the cut.如果您创建了一个生成主管的gen_server ,则意味着您在该级别中有所作为,而常规主管没有晋级。

Let's consider this OTP scenario:让我们考虑这个 OTP 场景:

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

Supervisors wait for all their children to have exited before terminating themselves, if you have a gen_server acting as a supervisor (G1) that dies for some reason before all its children (S1) have terminated, the parent may restart the gen_server (G1').主管在终止自己之前等待所有他们的孩子退出,如果您有一个作为主管(G1)的gen_server在其所有孩子(S1)终止之前由于某种原因死亡,则父母可能会重新启动gen_server (G1') . This one will spawn S1' which, in turn, will spawn C1'.这将产生 S1',而后者将产生 C1'。

Suddenly there are several instances of S1 and C1 running at the same time, and this may very well be a problem.突然有几个 S1 和 C1 的实例同时运行,这很可能是一个问题。

Regarding the code reload issue mentioned, it means that the code_changed callback tree trigger will stop at G1 (because G1 does not propagate it to S1), not that the code won't be loaded.关于提到的代码重载问题,这意味着code_changed回调树触发器将在 G1 处停止(因为 G1 不会将其传播到 S1),而不是不会加载代码。

TL;DR: Supervisors are very specialized gen_servers . TL;DR:主管是非常专业的gen_servers If you put a regular gen_server in the middle of a supervision tree without providing all the guarantees that the supervisor provides, you lose some of the OTP featrues in that subtree.如果您将常规gen_server放在监督树的中间,而没有提供监督者提供的所有保证,您将失去该子树中的一些 OTP 特性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM