【问题标题】:Erlang supervisor shutdowns after running childErlang 主管在运行孩子后关闭
【发布时间】:2017-05-02 16:21:33
【问题描述】:

我有一个测试模块和一个 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 中启动主管并运行命令 test:run(id, fun() -> erlang:throw(err) end). 它运行良好,函数 start_worker/1 重新启动三次,但之后发生异常并且主管进程关闭,我必须使用命令手动启动它 test_sup:start_link() .有什么问题?

壳牌:

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

【问题讨论】:

    标签: erlang erlang-otp erlang-supervisor


    【解决方案1】:

    有什么问题?

    没有“问题”。它的工作原理与you told it to

    为了防止主管进入子进程终止和重新启动的无限循环,使用上面映射中的键强度和周期指定的两个整数值定义最大重新启动强度。假设强度值 MaxR 和周期 MaxT 值,那么,如果在 MaxT 秒内发生超过 MaxR 重启,则主管终止所有子进程,然后终止自身。

    您的主管的配置显示,“如果我必须在 20 秒 (period) 内重新启动一个孩子超过两次 (intensity),那么就出了问题,所以请关闭。”至于为什么您必须手动重新启动主管,这是因为您的主管本身没有受到监督。否则,主管的主管可能会尝试根据自己的配置重新启动它。

    【讨论】:

      猜你喜欢
      • 2014-06-17
      • 2017-05-02
      • 2017-09-20
      • 2012-06-22
      • 1970-01-01
      • 2012-11-11
      • 2015-06-02
      • 2018-09-10
      • 2014-07-05
      相关资源
      最近更新 更多