elixir - Elixir Supervisor 如何阻止 child parking ?

标签 elixir erlang-supervisor

我有一个采用 :simple_one_to_one 重启策略的主管,当我调用 Supervisor.stop(sup) 时,子级会发生什么?

从测试中我发现,无论他们在做什么,他们都会死去。是否有标准方法可以优雅地关闭它们,以便它们可以完成工作(如果有)?比如对它们调用 GenServer.stop...

最佳答案

伊万.我认为你想限制你的员工退出。如果你不诱捕他们,他们就会被杀死。以下是我的意思的说明:

defmodule SupervisorStop do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [ worker(SupervisorStop.Worker, []) ]

    opts = [strategy: :simple_one_for_one, name: SupervisorStop.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

defmodule SupervisorStop.Worker do
  use GenServer
  require Logger

  def start_link(args) do
    GenServer.start_link(SupervisorStop.Worker, args, [])
  end

  def init(trap_exit) do
    Logger.info "#{inspect self} trap_exit: #{inspect trap_exit}"
    if trap_exit do
      Process.flag(:trap_exit, true)
    end
    {:ok, []}
  end

  def terminate(reason,_state) do
    Logger.info "terminating: #{inspect self}: #{inspect reason}"
    :ok
  end      
end

如果我在 iex 中运行它,会发生什么:

09:55:26 alex@alexmac test0 > iex -S mix
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Compiling 1 file (.ex)
Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Supervisor.start_child(SupervisorStop.Supervisor, [true])

09:59:16.086 [info]  #PID<0.102.0> trap_exit: true
{:ok, #PID<0.102.0>}
iex(2)> Supervisor.start_child(SupervisorStop.Supervisor, [false])
{:ok, #PID<0.104.0>}

09:59:21.113 [info]  #PID<0.104.0> trap_exit: false
iex(3)> Supervisor.stop(SupervisorStop.Supervisor)

09:59:35.702 [info]  terminating: #PID<0.102.0>: :shutdown
:ok
iex(4)>
09:59:35.710 [info]  Application test0 exited: normal

nil

正如您从输出中看到的那样,被捕获退出的工作线程在其死亡之前会调用其终止回调

09:59:16.086 [信息] #PID<0.102.0> trap_exit: true ... 09:59:35.702 [信息] 终止:#PID<0.102.0>: :shutdown

另一个 pid 没有报告其终止调用。那是因为

09:59:21.113 [信息] #PID<0.104.0> trap_exit: false

如果您确实想了解所有不同的组合,那么这篇文章非常有用:

http://crypt.codemancers.com/posts/2016-01-24-understanding-exit-signals-in-erlang-slash-elixir/

关于elixir - Elixir Supervisor 如何阻止 child parking ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41928315/

相关文章:

erlang - Simple_one_for_one 应用程序

associations - Ecto 与多个计划的关联

elixir - 构建对自身的 GenServer 调用的正确方法

elixir - 如何修改 Changeset 中的值 - Elixir?

erlang - 在 Elixir 中,依赖应用程序是否受到监督?

erlang - 收集有关 simple_one_for_one worker 的信息

erlang - 是否应该将客户端处理过程添加到主管树中?

elixir - 为 Mix 任务启动 Ecto(Mix.EctoSQL.ensure_started 不再工作)

elixir - 如何使用 Phoenix channel 直接回复用户的消息?

erlang-otp - 如何在 escript 中运行 Elixir Supervisor