Erlang 主管在 运行 child 后关闭

Erlang supervisor shutdowns after running child

我有一个测试模块和一个 one_for_one 主管。

test.erl

-module(test).

-export([do_job/1,run/2, start_worker/1]).


run(Id, Fun) ->
    test_sup:start_child(Id, [Fun]).


do_job(Fun) ->
    Fun().


start_worker(Args) ->
    Pid = spawn_link(test, do_job, Args),
    io:format("started ~p~n",[Pid]),
    {ok, Pid}.

test_sup.erl

-module(test_sup).
-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).
-export([start_child/2]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).


init(_Args) ->
    SupFlags = #{strategy => one_for_one, intensity => 2, period => 20},
    {ok, {SupFlags, []}}.


start_child(Id, Args) ->
    ChildSpecs = #{id => Id,
                    start => {test, start_worker, [Args]},
                    restart => transient,
                    shutdown => brutal_kill,
                    type => worker,
                    modules => [test]},

    supervisor:start_child(?MODULE, ChildSpecs).

现在我在 shell 和 运行 命令中启动 supervisor test:run(id, fun() -> erlang:throw(err) end). 它运行良好并且函数 start_worker/1 重新启动了三次但是在那之后,发生异常并且主管进程关闭,我必须使用命令 test_sup:start_link() 手动启动它。有什么问题?

Shell:

1> test_sup:start_link().
{ok,<0.36.0>}
2> test:run(id, fun() -> erlang:throw(err) end).
started <0.38.0>
started <0.39.0>
started <0.40.0>
{ok,<0.38.0>}

=ERROR REPORT==== 16-Dec-2016::23:31:50 ===
Error in process <0.38.0> with exit value:
{{nocatch,err},[{test,do_job,1,[]}]}

=ERROR REPORT==== 16-Dec-2016::23:31:50 ===
Error in process <0.39.0> with exit value:
{{nocatch,err},[{test,do_job,1,[]}]}

=ERROR REPORT==== 16-Dec-2016::23:31:50 ===
Error in process <0.40.0> with exit value:
{{nocatch,err},[{test,do_job,1,[]}]}
** exception exit: shutdown

What is the problem?

没有"problem"。它的工作方式与 you told it to:

完全一样

To prevent a supervisor from getting into an infinite loop of child process terminations and restarts, a maximum restart intensity is defined using two integer values specified with keys intensity and period in the above map. Assuming the values MaxR for intensity and MaxT for period, then, if more than MaxR restarts occur within MaxT seconds, the supervisor terminates all child processes and then itself.

你的supervisor的配置说,"If I have to restart a child more than two times (intensity) in 20 seconds (period), then something is wrong, so just shut down."至于你为什么要手动重启supervisor,那是因为你的supervisor本身没有被监管。否则supervisor的supervisor可能会根据自己的配置尝试重启。