我有一个测试模块和一个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()
。有什么问题?
外壳:
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
答案 0 :(得分:2)
有什么问题?
没有“问题”。它与you told it to完全相同:
为了防止主管进入子进程终止和重新启动的无限循环,使用在上面的映射中使用密钥强度和周期指定的两个整数值来定义最大重启强度。假设强度值MaxR和周期MaxT值,那么,如果在MaxT秒内发生超过MaxR重启,则主管终止所有子进程然后自己。
您的主管的配置说:“如果我必须在20秒内(intensity
)重启一个孩子两次以上(period
),那么就会出现问题,所以只需关闭。”至于为什么你必须手动重启主管,这是因为你的主管不是自己监督的。否则,主管的主管可能会尝试根据自己的配置重新启动它。