Erlang simple_one_for_one主管不会重新启动子级 [英] Erlang simple_one_for_one supervisor does not restart child

查看:108
本文介绍了Erlang simple_one_for_one主管不会重新启动子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测试模块和一个simple_one_for_one主管.

I have a test module and a simple_one_for_one supervisor.

test.erl

-module(test).

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

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


do_job(Fun) ->
    Pid = spawn(Fun),
    io:format("started ~p~n", [Pid]),
    {ok, Pid}.

test_sup.erl

test_sup.erl

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

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

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


init(_Args) ->
    SupFlags = #{strategy => simple_one_for_one, intensity => 2, period => 20},

    ChildSpecs = [#{id => test,
                    start => {test, do_job, []},
                    restart => permanent,
                    shutdown => brutal_kill,
                    type => worker,
                    modules => [test]}],

    {ok, {SupFlags, ChildSpecs}}.


start_child(Args) ->
    supervisor:start_child(?MODULE, Args).

我通过命令test_sup:start_link()在shell中启动超级用户.之后,我运行以下命令:test:run(fun() -> erlang:throw(err) end).除函数do_job之外,我重新启动了2次,但从未执行.有什么问题吗?

I start supervisor in shell by command test_sup:start_link(). After that i run this command: test:run(fun() -> erlang:throw(err) end). I except the function do_job restart 2times but it never does. What is the problem?

这是外壳:

1> test_sup:start_link().
{ok,<0.36.0>}
2> test:run(fun() -> erlang:throw(err) end).
started <0.38.0>
{ok,<0.38.0>}
3> 
=ERROR REPORT==== 16-Dec-2016::22:08:41 ===
Error in process <0.38.0> with exit value:
{{nocatch,err},[{erlang,apply,2,[]}]}

推荐答案

重新启动子级与定义simple_one_for_one主管的方式相反.根据主管文档:

Restarting children is contrary to how simple_one_for_one supervisors are defined. Per the supervisor docs:

delete_child/2和restart_child/2函数对于simple_one_for_one主管无效,如果指定的主管使用此重启策略,则返回{error,simple_one_for_one}.

Functions delete_child/2 and restart_child/2 are invalid for simple_one_for_one supervisors and return {error,simple_one_for_one} if the specified supervisor uses this restart strategy.

换句话说,您要的东西永远不会发生.这是因为simple_one_for_one用于动态子级,这些动态子级在您请求子级时通过传入其他启动arg来动态定义.其他主管可以重新启动其子级,因为在该主管中静态定义了启动args.

In other words, what you're asking for can never happen. That's because a simple_one_for_one is intended for dynamic children that are defined on the fly by passing in additional startup args when you request the child. Other supervisors are able to restart their children because the startup args are statically defined in the supervisor.

基本上,这种类型的主管是为了确保在需要动态工作人员池时有条不紊地关闭计算机.

Basically, this type of supervisor is strictly for ensuring a tidy shutdown when you need to have a dynamic pool of workers.

这篇关于Erlang simple_one_for_one主管不会重新启动子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆