2017-11-29 2 views
2

supervisor을 사용하여 gen_fsm을 생성하고 모니터링하고 있습니다. 특정 상황에서는 gen_fsm이 종료됩니다. 나중에 supervisor은 이전에 적용한 것과 동일한 id 아래에 새로운 gen_fsm을 생성합니다.등록 된 gen_fsm이 자체 감독자에게 자신을 삭제할 수 있습니까?

특히 gen_fsm은 (는) 감독 chatbots입니다. 동일한 사용자가 동일한 채팅 표시 줄에 대해 이야기해야합니다. 사용자가 더 이상 봇과 통신하지 않으면 봇이 종료됩니다. 여기서 봇에게 감독관으로부터 등록 해제를 요청하지만 어느 당사자가 supervisor:delete_child/2을 시작해야하는지 알지 못합니다.

terminate/3 (gen_fsm) 중에 전화해야합니까? 도와주세요.

UPDATE는

은 다음이가 아이 사양의 transient 다시 시작이 무엇인지 내 REPO https://github.com/khanhhua/erlbot

답변

2
+0

사실 'transient'를 사용합니다. 하지만 그건 문제가 아닙니다. 여기 내 레포 https://github.com/khanhhua/erlbot –

+1

적어도'erlbot_bot'에서는'transient'의 혜택을받는 정상적인 이유로 봇을 멈추는 곳을 어디에도 볼 수 없습니다. –

+0

보세요. 고마워. 그것은 branch feat/start-bot에 있습니다. 여기 https://github.com/khanhhua/erlbot/blob/feat/start-bot/src/erlbot_bot.erl –

-1

읽기 위해 코드 (죄송합니다)하지만 OTP/Supervisor으로 할 수 없다면 나는 좋습니다. Director을 사용하십시오.

0

@Alexey와 @Vladimir을 입력 해 주셔서 감사합니다. 문제를 해결했습니다.

내 문제의 핵심은 아직도 내가 DeadChildSpecPidChildSpec이 적용됩니다 결정하기 위해 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과 함께 시작해야합니다 감독 transientrestart_type
  • 감독 gen_fsm{stop, shutdown} 자신을 종료해야 (긍정을 위해, 알렉세이 감사합니다) 또는 {stop, normal} (확인을 위해 블라디미르에게 감사드립니다.)
  • 감독자는 이후에 정리를해야합니다. gen_fsm이 "싱글 톤"을 보증합니다.
  • gen_fsm:terminate/3{error, running}이 될 수 있으므로 supervisor:delete_child이 아니어야합니다.
+0

은 테스트에서 인쇄 된 "Bot ~ p was deadbot ~ n"이었습니까? –

+0

@LynHeadley 예! '{stop, normal}'또는'{stop, shutdown} '전환 이후. –

관련 문제