I have been trying to monitor a gen_server using erlang:monitor/2. Unfortunately every time I try this the Erlang shell goes into an infinite loop.
Here is the test program i've written to test this out.
-module(testmon).
-compile(export_all).
start() ->
{ok,Proc} = gen_server:start(calc,[],[]),
erlang:monitor(process,Proc),
receive
{'DOWN', Ref, process, Pid, normal} ->
io:format("~p said that ~p died by natural causes~n",[Ref,Pid]);
{'DOWN', Ref, process, Pid, Reason} ->
io:format("~p said that ~p died by unnatural causes~n~p",[Ref,Pid,Reason])
end.
When I use the above code to monitor something like this spawn(fun() -> ok end) (by changing lines 6 and 7) to erlang:monitor(spawn(fun() -> ok end)) the above code works as intended.
Can someone please show me what i am doing wrong? Is it only possible to monitor a gen_server process via a supervisor?
Thank you
It's not an infinite loop (there are no loops in Erlang at all), your shell just blocks in receive until the gen_server dies for some reason. If you want shell to return immediately just spawn an additional process to do the monitoring. It does not have to be gen_supervisor, your code in separate process should walk as intended.
This can look something like this:
-module(testmon).
-compile(export_all).
start() ->
{ok,Proc} = gen_server:start(calc,[],[]),
spawn(?MODULE, monitor, [Proc]).
monitor(Proc) ->
erlang:monitor(process,Proc),
receive
{'DOWN', Ref, process, Pid, normal} ->
io:format("~p said that ~p died by natural causes~n",[Ref,Pid]);
{'DOWN', Ref, process, Pid, Reason} ->
io:format("~p said that ~p died by unnatural causes~n~p",[Ref,Pid,Reason])
end.