Elixir主管如何阻止儿童停止?

时间:2017-01-30 02:35:17

标签: elixir supervisor

我有一位主管:simple_one_to_one重新启动策略,当我致电Supervisor.stop(sup)时,孩子会怎么样?

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

2 个答案:

答案 0 :(得分:1)

伊凡。我想你想要让你的工人退出。如果你没有陷阱,他们就会被杀死。以下是我的意思:

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 [info] #PID&lt; 0.102.0&gt; trap_exit:true    ...    09:59:35.702 [info]终止:#PID&lt; 0.102.0&gt;::shutdown

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

09:59:21.113 [info] #PID&lt; 0.104.0&gt; trap_exit:false

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

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

答案 1 :(得分:1)

用这篇伟大的文章来解释:&#34;谁监督上司&#34;

  

当要求顶级主管终止时,它会在每个Pids上调用exit(ChildPid,shutdown)。如果孩子是工人并且陷阱退出,它将调用自己的终止功能。否则,它就会死去。当主管获得关机信号时,它会以同样的方式将其转发给自己的孩子。

简而言之,如果你想优雅地关闭一个工人:

  • 陷阱退出
  • 处理其terminate功能
  • 中的关机

来源:http://learnyousomeerlang.com/supervisors