如何在 Elixir 主管中引用之前启动的进程

Posted

技术标签:

【中文标题】如何在 Elixir 主管中引用之前启动的进程【英文标题】:How to reference previously started processes in an Elixir supervisor 【发布时间】:2017-11-23 15:11:15 【问题描述】:

我正在创建一个监控两个孩子的主管。第二个孩子需要参考第一个孩子。这样的接缝应该是可能的,因为通过使用one_for_rest 策略,我可以确保如果第一个死了,第二个会重新启动。

children = [
  supervisor(SupervisorA, [arg1]),
  supervisor(SupervisorB, [arg2, ref_to_supervisor_a_process]),
]

supervise(children, strategy: :one_for_rest)

理想情况下,无需全局命名任一进程。

【问题讨论】:

【参考方案1】:

SupervisorA 可以将name: 选项提供给Supervisor.start_link/3

SupervisorB 然后可以使用Process.whereis/1 将名称解析为pid,或者只是向指定的进程发送消息。

https://hexdocs.pm/elixir/Supervisor.html#start_link/3 https://hexdocs.pm/elixir/Process.html#whereis/1

【讨论】:

您好,谢谢,我的目标是不必为任一进程使用全局名称。运行这两个监督者的监督者可能会多次启动 注册表怎么样? hexdocs.pm/elixir/Registry.html#content 我不确定注册表是否提供任何价值,我仍然必须在注册表中提供一个随机键以避免多次启动***主管所需的冲突 看起来 elixir 1.5 有一个挂钩子初始化过程的工具:hexdocs.pm/elixir/master/Supervisor.html#init/2 我认为它一直存在,除非我弄错了这实际上没有帮助【参考方案2】:

Supervisor.Spec.supervisor/3 返回一个spec

可能会通过:

id, _, _, _, _, _ = sup_a = supervisor(SupervisorA, [arg1])
children = [
  sup_a,
  supervisor(SupervisorB, [arg2, id]),
]

【讨论】:

有很多方法可以通过id检索PID,例如。 G。 Supervisor.which_children/1。即使原始进程死亡并且 PID 发生变化,后者仍然有效。 您是否也不需要传递对主管 pid 的引用【参考方案3】:

我建议使用Director 而不是主管模块。 在重启、删除等方面更加灵活和强大。

【讨论】:

你可以使用director:get_pid/2函数获取特定子id的pid。 孩子引用启动它的主管是否正常

以上是关于如何在 Elixir 主管中引用之前启动的进程的主要内容,如果未能解决你的问题,请参考以下文章

使用主管为每个节点启动 elixir 子进程

Elixir - 基本主管设置崩溃而不是重新启动子进程

如何在 Elixir 中建模主管树

在 Elixir ExUnit 中,我如何保证 Supervisor 将创建一个新的 GeNserver?

Elixir 与 Mix 如何制作守护进程?

如何通过在 Elixir 中调用进程来捕获或挽救被调用进程的崩溃错误