I\'m very new to OTP, I\'m trying to create simple example to understand supervisor behaviour:
Here is simple increment server
-module( inc_serv ).
-
This is actually a kind of race condition.
As you might know, the Erlang shell itself is a normal Erlang process. When you start your supervisor from the shell, the supervisor is linked to the shell (because you use supervisor:start_link/3
).
When you call your gen_server process, that process crashes (and is correctly restarted by the supervisor, as you can see by the subsequent "Increment server started :)"
output).
However, at the same time, your call to gen_server:call/2
will result in the same crash (a gen_server crashing during the call will emit the same crash through the gen_server:call/2
function). This then crashes the shell process, which is linked to your supervisor, which in turn crashes with the same reason (badarith
).
Basically, your supervisor is backstabbed by your shell process, after it loyally restarted your gen_server. Like so:
+---------(6)exit----------+ +---------(5)restart---------+
| | | |
| v | v
Shell ---(1)start_link---> supervisor ---(2)start_link---> gen_server
| ^ ^ | ^ | ^
| | | | | | |
| | | +---------(7)exit---------+ | |
| | | | |
| +-------------------------+--------------(4)exit------------+ |
| |
+---------------------------(3)call--------------------------------+
You can avoid this by calling catch inc_serv:inc(bad_arg).
in your shell:
90> inc_serv:inc(7).
8
91> catch inc_serv:inc(bad_arg).
"Increment server stopped"
=ERROR REPORT==== 23-Aug-2012::22:10:02 ===
** Generic server inc_serv terminating
** Last message in was {num,bad_arg}
** When Server state == no_state
** Reason for termination ==
** {badarith,[{inc_serv,handle_call,3,[{file,"inc_serv.erl"},{line,20}]},
{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,227}]}]}
"Increment server started :)"
{'EXIT',{{badarith,[{inc_serv,handle_call,3,
[{file,"inc_serv.erl"},{line,20}]},
{gen_server,handle_msg,5,
[{file,"gen_server.erl"},{line,588}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,227}]}]},
{gen_server,call,[inc_serv,{num,bad_arg}]}}}
92> inc_serv:inc(7).
8