2016-12-16 23 views
0

我有一個測試模塊和一個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). 

現在,我開始在外殼監事和運行命令test:run(id, fun() -> erlang:throw(err) end).它的工作好和功能start_worker/1重啓3次,但在那之後,異常發生並且主管進程關閉,我必須用命令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 

回答

2

問題是什麼?

沒有「問題」。它的工作完全一樣you told it to

爲了防止主管從進入子進程終止並重新啓動,最大重啓強度使用具有鍵的強度和週期在上述映射中指定兩個整數值定義的無限循環。假設強度值爲MaxR,週期爲MaxT,那麼如果超過MaxR重新啓動發生在MaxT秒內,監督員終止所有子進程,然後自行終止。

你的上司的配置說,「如果我有20秒(period)重新啓動一個孩子兩次以上(intensity),那麼什麼是錯的,所以才關閉。」至於爲什麼你必須手動重啓主管,這是因爲你的主管沒有受到自我監督。否則,主管的主管可能會嘗試根據自己的配置重新啓動它。