gen_server
dokumentację Module:terminate
zwrotnego mówi:Nienadzorowany gen_server nie wymaga wypowiedzenia, gdy odbiera sygnał EXIT
Nawet jeśli proces gen_server nie jest częścią drzewa nadzoru, to funkcja jest wywoływana w przypadku otrzymania Wiadomość "EXIT" od rodzica. Powód jest taki sam jak w komunikacie "WYJŚCIE".
Oto moja handle_info
i terminate
funkcja:
handle_info(UnknownMessage, State) ->
io:format("Got unknown message: ~p~n", [UnknownMessage]),
{noreply, State}.
terminate(Reason, State) ->
io:format("Terminating with reason: ~p~n", [Reason]).
zacznę ten serwer przy użyciu gen_server:start
. Zakładam, że gdy zadzwonię pod numer erlang:exit(Pid, fuckoff)
, powinien zadzwonić pod numer terminate
. Ale pokazuje:
Got unknown message: {'EXIT',<0.33.0>,fuckoff}
Co oznacza, że dzwoni handle_info
. Ale kiedy zadzwonię pod numer gen_server:stop
, wszystko działa zgodnie z dokumentacją. Dzwonię pod numer gen_server
z powłoki. Czy mógłbyś to wyjaśnić?
[Update]
Here jest kod źródłowy decode_msg
funkcji wewnątrz gen_server
. Jeśli nie otrzyma żadnej wiadomości „exit” powinien zadzwonić terminate
funkcję:
decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) ->
case Msg of
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
[Name, State, Mod, Time], Hib);
{'EXIT', Parent, Reason} ->
terminate(Reason, Name, Msg, Mod, State, Debug);
_Msg when Debug =:= [] ->
handle_msg(Msg, Parent, Name, State, Mod);
_Msg ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
Name, {in, Msg}),
handle_msg(Msg, Parent, Name, State, Mod, Debug1)
end.
W moim przypadku nie wymaga terminate
funkcję.
[UPDATE]
Kiedy zacznę gen_server
użyciu gen_server:start_link()
, wysyłając sygnał wyjściowy używając erlang:exit(Pid, Reason)
spowoduje wywołanie terminate
oddzwonię funkcję, która jest oczekiwane zachowanie. Wydaje się, że istnieje różnica w interpretacji sygnału wyjściowego, niezależnie od tego, czy proces jest powiązany z rodzicem czy nie.
Czy ustawiłeś flagę 'trap_exit' procesu na' true' gdzieś w kodzie? –
Tak. Wewnątrz funkcji 'init'. –