Как обнаружить отключение erl_call
У меня есть сервис erlang, который запускается erl_call. erl_call сделает длинный вызов типа "gen_server:call(?SERVER, do, infinity)", чтобы дождаться результата. Если служба erlang не работает, erl_call вернется. Но если erl_call будет прерван (используйте CTRL-C), служба erlang не получит никакого сообщения.
Я проверяю с appmon и pman. Процесс, который запустил erl_call, не прекращается после отключения erl_call. Так что ссылка / монитор на этот процесс не работает. Как определить, что erl_call уже отключен?
1 ответ
В вашей функции handle_call есть секунда. аргумент From:: {pid(), tag()}
Вы можете вызвать monitor(process, FromPid) в handle_call перед обработкой запроса, чтобы вы получили сообщение DOWN, когда ваш узел erl_call отключается. Но обратите внимание, что вы не сможете обработать сообщение DOWN до завершения текущего handle_call, если вы не породите отдельный процесс или не используете отложенный ответ с помощью gen_server:reply().
Например: вот наше предложение handle_call:
handle_call(test, {From, _}=X, State) ->
erlang:monitor(process, From),
spawn(fun() ->
timer:sleep(10000),
io:format("### DONE~n", []),
gen_server:reply(X, ok) end),
{noreply, State}.
Далее мы ловим ВНИЗ:
handle_info(Info, State) ->
io:format("### Process died ~p~n", [Info]),
{noreply, State}.
Далее я вызываю erl_call из командной строки: erl_call -c 123 -n test -a 'gen_server call [a, test, infinity]'
и нажмите Ctrl-C
в консоли gen_server через 10 сек я вижу:
### DONE
### Process died {'DOWN',#Ref<0.0.0.41>,process,<0.44.0>,normal}