gpt4 book ai didi

elixir - Supervisor.restart_child/2 或 Process.exit(pid, :kill)?

转载 作者:行者123 更新时间:2023-12-04 12:39:11 25 4
gpt4 key购买 nike

我有一个监督树,为了简单起见,假设一名监督员 (S) 持有一名 worker (W) 和 :one_for_one战略。

在某些情况下,我需要重新初始化W最简单的方法就是让它崩溃。我有两种不同的选择: Process.exit/2 和/或 Supervisor.restart_child/2 :

Process.exit(W, :kill)



[{id, _, :worker, _}] = Supervisor.which_children(S)
Supervisor.terminate_child(S, w_id)
Supervisor.restart_child(S, w_id)

由于后者存在,我想它可能会更好用,但我不知道使用它会有什么好处。假设是策略 :rest_for_one和许多 child ,前者将重新启动 worker 列表的整个尾部,而后者将仅重新启动该特定 worker 。我找不到任何合理的文档,也没有在代码库中发现这种差异。

所以,问题是:当使用策略 :one_by_one通过 terminate 是否有意义? → restart循环或 Process.exit(pid, :kill)够不够?

最佳答案

除了 worker 在使用 Process.exit/2 时对退出信号有发言权,这可能与您的场景不完全相关(尽管可能会 Hook 退出信号陷阱所需的任何重新初始化以避免重新启动工作人员),这可能是相关的。
方法 A .当Process.exit(W, :kill)被调用,这是发生的事情:

  • 工作进程被终止
  • 主管receives 'EXIT' 来自终止 worker 的信号
  • 主管调用 restart_child/3 哪个根据指定的重启策略

  • 很瘦很刻薄。
    方法 B .使用另一种手动方法会发生以下情况:
  • terminate_child/2 最终调用shutdown/2
  • shutdown/2 默认情况下会尝试优雅地关闭子进程,使其有机会释放任何系统资源
  • 如果 child 在超时后没有退出,它会被杀死
  • 自从 child gets unlinked在关闭之前,主管没有收到 'EXIT'信号并且不会自动重启子进程
  • 下一个电话,restart_child(S, w_id)重新启动子进程,重用其规范并规避重启策略

  • 对于 方法 A 要适用, child 不得分配外部资源。与 one_for_one strategy 它是一条不错的捷径,在其限制范围内很有用。使用其他策略会导致其他 child 可能无用和/或昂贵的重新启动。当约束不是问题时,这种方法可能是对稳定解决方案的合理优化。
    方法 B 是一种更通用的方法来控制单个子项重新启动。它确实涉及更复杂的逻辑,以提供优雅的行为作为交换。它还允许在子终止和重新启动之间放置额外的逻辑。额外的好处是即使使用 rest_for_one 也能精确地重新启动目标子节点。或 one_for_all策略。在我看来,对于不断发展的应用程序来说,这是一个更好的选择,因为它不受特定约束的限制,允许更轻松地更改实现。

    关于elixir - Supervisor.restart_child/2 或 Process.exit(pid, :kill)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51651731/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com