@Alexey와 @Vladimir을 입력 해 주셔서 감사합니다. 문제를 해결했습니다.
내 문제의 핵심은 아직도 내가 DeadChildSpec
의 Pid
는 ChildSpec
이 적용됩니다 결정하기 위해 undefined
여부를 확인해야한다 따라서 Children = [DeadChildSpec]
get_bot(Username) ->
Children = supervisor:which_children({global, ?SERVER}),
%% {Name, Pid, ChildType, Mods}
case lists:keyfind(Username, 1, Children) of
{Name, BotPid, _ChildType, _Mods} ->
if
BotPid =:= undefined ->
supervisor:delete_child({global, ?SERVER}, Name),
{error, deadbot};
true -> {ok, BotPid}
end;
false -> {error, not_found}
end.
을 의미 자식 사양의 목록을 유지하는 것이 관리자 erlbot_sup
입니다 create_bot
동안 삭제하십시오.
create_bot(Username) ->
%% Bots are "singletons"
Result = case get_bot(Username) of
{error, Error} when (Error =:= not_found) or (Error =:= deadbot) ->
if
Error =:= deadbot -> io:format("Bot ~p was a deadbot~n", [Username]);
true -> true
end,
MFA = {erlbot_bot,start_link,[Username]},
supervisor:start_child({global, ?SERVER},
#{id => Username,
start => MFA,
restart => transient,
type => worker
});
{ok, BotPid} -> {ok, BotPid}
end,
io:format("Result: ~p~n", [Result]),
Result.
그래서 - 내 질문에 대한 답은 다음과 같습니다
gen_fsm
과 함께 시작해야합니다 감독 transient
restart_type
- 감독
gen_fsm
가 {stop, shutdown}
자신을 종료해야 (긍정을 위해, 알렉세이 감사합니다) 또는 {stop, normal}
(확인을 위해 블라디미르에게 감사드립니다.)
- 감독자는 이후에 정리를해야합니다.
gen_fsm
이 "싱글 톤"을 보증합니다.
gen_fsm:terminate/3
은 {error, running}
이 될 수 있으므로 supervisor:delete_child
이 아니어야합니다.
사실 'transient'를 사용합니다. 하지만 그건 문제가 아닙니다. 여기 내 레포 https://github.com/khanhhua/erlbot –
적어도'erlbot_bot'에서는'transient'의 혜택을받는 정상적인 이유로 봇을 멈추는 곳을 어디에도 볼 수 없습니다. –
보세요. 고마워. 그것은 branch feat/start-bot에 있습니다. 여기 https://github.com/khanhhua/erlbot/blob/feat/start-bot/src/erlbot_bot.erl –