主管:
-module(mod_guild_chapter_sup).
-include("guild_dungeon.hrl").
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%===================================================================
%%% API functions
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% Starts the supervisor
%%
%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
%% @end
%%--------------------------------------------------------------------
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever a supervisor is started using supervisor:start_link/[2,3],
%% this function is called by the new process to find out about
%% restart strategy, maximum restart frequency and child
%% specifications.
%%
%% @spec init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
%% ignore |
%% {error, Reason}
%% @end
%%--------------------------------------------------------------------
init([]) ->
RestartStrategy = simple_one_for_one,
MaxRestarts = 1000,
MaxSecondsBetweenRestarts = 3600,
SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},
Restart = transient,
Shutdown = 60000,
Type = worker,
ModGuildChapter = {'guild_chapter', {'mod_guild_chapter', start_link, []},
Restart, Shutdown, Type, ['mod_guild_chapter']},
{ok, {SupFlags, [ModGuildChapter]}}.
孩子:
-module(mod_guild_chapter).
-record(state, {}).
start_link(GuildId, ChapterId) ->
gen_server:start_link(?MODULE, [GuildId, ChapterId], []).
init([GuildId, ChapterId]) ->
case condition() of
true -> ignore;
false -> {ok, #state{})
end.
...omit other callbacks...
supervisor:which_children(mod_guild_chapter_sup)
:
[{undefined,<0.9635.0>,worker,[mod_guild_chapter]},
{undefined,<0.9539.0>,worker,[mod_guild_chapter]},
{undefined,<0.9475.0>,worker,[mod_guild_chapter]},
{undefined,<0.9493.0>,worker,[mod_guild_chapter]},
{undefined,<0.9654.0>,worker,[mod_guild_chapter]},
{undefined,undefined,worker,[mod_guild_chapter]},
{undefined,<0.9658.0>,worker,[mod_guild_chapter]},
{undefined,<0.9517.0>,worker,[mod_guild_chapter]},
{undefined,<0.9567.0>,worker,[mod_guild_chapter]}]
收到{0}时的例外:
shutdown
如您所见,有一个2015-07-03 14:56:33 =CRASH REPORT====
crasher:
initial call: mod_guild_chapter:init/1
pid: <0.9475.0>
registered_name: []
exception exit: {{function_clause,[{supervisor,'-monitor_dynamic_children/2-fun-1-',[undefined,[100062,10003],{{set,3,16,16,8,80,48,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[],[],[],[],[],[],[],[<0.9658.0>],[],[],[<0.9517.0>],[],[<0.9567.0>],[],[],[]}}},{dict,0,16,16,8,80,48,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}}],[{file,"supervisor.erl"},{line,992}]},{dict,fold_bucket,3,[{file,"dict.erl"},{line,441}]},{dict,fold_seg,4,[{file,"dict.erl"},{line,437}]},{dict,fold_segs,4,[{file,"dict.erl"},{line,433}]},{supervisor,terminate_dynamic_children,3,[{file,"supervisor.erl"},{line,959}]},{gen_server,terminate,6,[{file,"gen_server.erl"},{line,719}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]},[{gen_server,terminate,6,[{file,"gen_server.erl"},{line,744}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}
ancestors: [mod_guild_chapter_sup,mod_guild_sup,yg_sup,<0.82.0>]
messages: []
links: []
dictionary: []
trap_exit: true
status: running
heap_size: 1598
stack_size: 27
reductions: 6586
neighbours:
pid,不应该存在。
文件中有两处解释了这一点,但它们之间存在冲突。
undefined
即使它返回temporary
,孩子的规范将由主管保管。start定义用于启动子进程的函数调用。它必须是用作apply(M,F,A)的模块函数参数元组{M,F,A}。
start函数必须创建并链接到子进程,并且必须返回{ok,Child}或{ok,Child,Info},其中Child是子进程的pid,Info是任意一个被忽略的术语。主管。
如果由于某种原因导致子进程无法启动,则start函数也可以返回ignore,在这种情况下,子进程将由主管保存(除非它是临时子进程),但是不存在的子进程将是忽略。
ignore
,simple_one_for_one
pid将不会添加到主管。如果子进程启动函数返回ignore,则将子规范添加到超级用户(除非超级用户是一个simple_one_for_one超级用户,见下文),pid设置为undefined,函数返回{ok,undefined}。 / p>
对于simple_one_for_one管理程序,当子进程启动函数返回忽略时,函数返回{ok,undefined}并且没有子进程添加到主管。
我对文件感到困惑。我选择ignore
重新启动策略,因为子应该在崩溃时重新启动。但是我怎么能在这里避免这个例外呢?
答案 0 :(得分:0)
好的,我再次阅读你的问题。文档说明如果你在孩子的启动功能中返回忽略,则该孩子不启动。对于simple_one_for_one监督者,也不会保留子规范(这是合乎逻辑的,因为在监督者的开始只保存了一个规范)。这意味着该行:
{undefined,undefined,worker,[mod_guild_chapter]},
只是说没有启动子进程。因此,该过程不能成为您例外的原因。崩溃报告为您提供崩溃过程的pid,其为&lt; 0.9475.0&gt;。您可以在which_children的返回列表中找到它。这是检查发现崩溃原因的过程。