I have an erlang service that trigged by erl_call. erl_call will make a long call like "gen_server:call(?SERVER, do, infinity)" to wait the result. If erlang service down, erl_call will return. But if erl_call be interrupted (use CTRL-C), the erlang service do not receive any message.
I check with appmon and pman. The process that erl_call started not die after erl_call disconnected. So link/monitor to that process is not work. How do I detect erl_call already disconnected?
In your handle_call function there is a second. argument From :: {pid(), tag()}
You can call monitor(process, FromPid) in handle_call before processing the request so you'll receive DOWN message when your erl_call node disconnects. But note that you won't be able to process DOWN message before current handle_call completes unless you spawn a separate process or use delayed reply with gen_server:reply().
For example: here's our handle_call clause:
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}.
Next we catch DOWN:
handle_info(Info, State) ->
io:format("### Process died ~p~n", [Info]),
{noreply, State}.
Next I spawn erl_call from command line: erl_call -c 123 -n test -a 'gen_server call [a, test, infinity]'
and hit Ctrl-C
in gen_server console after 10 sec I see:
### DONE
### Process died {'DOWN',#Ref<0.0.0.41>,process,<0.44.0>,normal}