Как обнаружить отключение 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}
Другие вопросы по тегам