gen_server named timer_server caused timer module functions to not return
Question
I created a supervisor that spawned a gen_server
I called timer_server
. One of the tasks of this timer_serve
r is to manage registration and call timer:send_interval
to send a message to a pid on a certain interval.
However, in the init of the gen_server
, where I call timer:send_interval
I was getting a lockup. The documentation said the timer: functions return immediately, so this was very troubling.
When I renamed my gen_server
to record_timer_server
this problem cleared up. My question is two fold then:
- Why could I create a registered process
timer_server
, if there already was one whentimer:start()
was called by my application starting up? - Once started, why would this function not cause a badmatch finding the name, if it was calling in to my
timer_server
using thesend_interval
function?
I don't think code is necessary but I can update to add some if requested.
Solution
This can be recreated simply by doing the following which hangs on the call to timer:send_interval.
1> register(timer_server, self()).
true
2> timer:send_interval(5000, self(), hello).
While this fails...
1> timer:send_interval(5000, self(), hello).
{ok,{interval,#Ref<0.0.0.32>}}
2> register(timer_server, self()).
** exited: {badarg,[{erlang,register,[timer_server,<0.30.0>]},
So, it seems that the first call to timer tries to start a process called timer_server, and hangs if you've taken this name first.
As to why it hangs timer.erl does:
ensure_started() ->
case whereis(timer_server) of
undefined ->
C = {timer_server, {?MODULE, start_link, []}, permanent, 1000,
worker, [?MODULE]}
supervisor:start_child(kernel_safe_sup, C), % kernel_safe_sup
ok;
_ -> ok
end.
which returns fine, followed by a gen_server:call to timer_server. Your process then gets stuck waiting for itself to respond.