【问题标题】:More than one Supervisor in Elixir ApplicationElixir 应用程序中的多个主管
【发布时间】:2019-04-23 18:06:08
【问题描述】:

我想在我的 Phoenix 应用程序中注册 2 个 root 主管,有什么理由不这样做吗?

示例如下

defmodule MyApp.Application do
  use Application
  import Supervisor.Spec

  def start(_type, _args) do
    children_sv1 = [
      supervisor(MyApp.Repo, []),
      ... # other workers
    ]

    children_sv2 = [
      supervisor(MyApp.Endpoint, []),
      ... # other workers
    ]

    opts1 = [strategy: :one_for_one, name: MyApp.Supervisor1]
    opts2 = [strategy: :one_for_one, name: MyApp.Supervisor2]

    Supervisor.start_link(children_sv1, opts)
    Supervisor.start_link(children_sv2, opts)
  end
end

【问题讨论】:

  • 没有理由不这样做,尽管在这种情况下只会引用第二个,因为它将作为start/2 调用的结果返回。有一个小的example here,您可以将主管放入单独的文件并从这里调用它们。

标签: elixir phoenix-framework


【解决方案1】:

不这样做的一个原因是您的特定应用程序本身作为 OTP 范围的监督树的一部分受到监督。 start 的返回值被顶级应用程序主管用来监督您的特定应用程序。

如果您将结果显式分配给上述主管调用,您将看到您正在删除信息:

{:ok, sup1_pid} = Supervisor.start_link(children_sv1, opts)
{:ok, sup2_pid} = Supervisor.start_link(children_sv2, opts)
{:ok, sup2_pid}

这意味着虽然第一个监督者将链接到正在启动您的应用程序的任何进程(例如顶级应用程序监督者),但它不会出现在查看监督树的函数的输出中,例如 Supervisor.count_children。在正常操作期间,这应该没什么大不了的,但如果出现任何问题,您自己可能很难剖析问题,并且依赖于适当监督层次结构的 OTP 工具在面对这种设置时可能会表现得很奇怪。优雅地停止应用程序可能是也可能不是问题。

将整个监督树指定为适当的树总是更安全的选择——您最终会得到一个更可预测的应用程序。如果您需要精细控制树的哪些分支是独立的以及应该如何重新启动它们,子规范是您最好的朋友。

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 2019-02-09
    • 2013-09-23
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多