[erlang-questions] gen_server restarted by supervisor not working right
Jack Orenstein
jao@REDACTED
Wed Oct 17 06:42:36 CEST 2007
I've been going through various pieces of OTP documentation and trying
to put together my own simple code that demonstrates a supervisor
restarting a server.
I see the server starting and then crashing, (the test driver sends a
message that calls exit/1). I see the restart, but then the program
exits, apparently before the test driver's attempt to send a message
to the restarted server.
Here is the test driver, test.erl:
-module(test).
-export([main/0]).
-include_lib("cluster.hrl").
main() ->
?DUMP(cluster_supervisor:start_in_shell_for_testing()),
?DUMP(region_server:hello(world)),
?DUMP(region_server:crash()),
?DUMP(region_server:hello(again)).
The rest of the code appears below, but here is the test output:
region_server:52 - "{ start_link , RegionNumber }" = {start_link,0}
region_server:23 - "{ init , ? MODULE , RegionNumber }" = {init,
region_server,
0}
test:8 - "cluster_supervisor : start_in_shell_for_testing ( )" =
true
region_server:56 - "{ hello , X }" = {hello,world}
region_server:30 - "{ hello , X }" = {hello,world}
test:9 - "region_server : hello ( world )" = {hello,world,0}
region_server:60 - "crash" = crash
region_server:33 - "{ crash , RegionNumber }" = {crash,0}
region_server:43 - "{ terminate , ? MODULE }" =
{terminate,region_server}
=ERROR REPORT==== 17-Oct-2007::00:30:41 ===
** Generic server region_server terminating
** Last message in was {crash}
** When Server state == 0
** Reason for termination ==
** {crash,0}
region_server:52 - "{ start_link , RegionNumber }" = {start_link,0}
region_server:23 - "{ init , ? MODULE , RegionNumber }" = {init,
region_server,
0}
{"init terminating in do_boot",{{crash,0},{gen_server,call,
[region_server,{crash}]}}}
Crash dump was written to: erl_crash.dump
init terminating in do_boot ()
The output from region_server:hello(world), before the crash, appears;
but the output from region_server:hello(again), does not.
What am I doing wrong?
Jack Orenstein
Other modules:
Here is cluster_supervisor:
-module(cluster_supervisor).
-behavior(supervisor).
-export([start/0,
start_in_shell_for_testing/0,
start_link/1,
init/1]).
-include_lib("cluster.hrl").
start() ->
spawn(fun() ->
supervisor:start_link({local, ?MODULE}, ?
MODULE, [])
end).
start_in_shell_for_testing() ->
{ok, P} = supervisor:start_link({local, ?MODULE}, ?MODULE, []),
unlink(P).
start_link(Args) ->
supervisor:start_link({local, ?MODULE}, ?MODULE, Args).
init([]) ->
{ok, {{one_for_one, 3, 10},
[{region0,
{region_server, start_link, [0]},
permanent,
10000,
worker,
[region_server]}
]}}.
And here is region_server:
-module(region_server).
-behavior(gen_server).
-include_lib("cluster.hrl").
%% gen_server api
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).
%% region_server api
-export([start_link/1,
hello/1,
crash/0]).
%% gen_server api
init([RegionNumber]) ->
process_flag(trap_exit, true),
?DUMP({init, ?MODULE, RegionNumber}),
{ok, RegionNumber}.
handle_call({region}, _From, RegionNumber) ->
?DUMP({region, RegionNumber}),
{reply, {region, RegionNumber}, RegionNumber};
handle_call({hello, X}, _From, RegionNumber) ->
?DUMP({hello, X}),
{reply, {hello, X, RegionNumber}, RegionNumber};
handle_call({crash}, _From, RegionNumber) ->
?DUMP({crash, RegionNumber}),
exit({crash, RegionNumber}).
handle_cast(_Cast, N) ->
{noreply, N}.
handle_info(_Info, N) ->
{noreply, N}.
terminate(_Readon, _N) ->
?DUMP({terminate, ?MODULE}),
ok.
code_change(_, N, _) ->
{ok, N}.
%% region_server api
start_link(RegionNumber) ->
?DUMP({start_link, RegionNumber}),
gen_server:start_link({local, ?MODULE}, ?MODULE,
[RegionNumber], []).
hello(X) ->
?DUMP({hello, X}),
gen_server:call(?MODULE, {hello, X}).
crash() ->
?DUMP(crash),
gen_server:call(?MODULE, {crash}).
The DUMP macro is defined in cluster.hrl:
-define(DUMP(X), io:format("~p:~p - ~p = ~p~n", [?MODULE, ?
LINE, ??X, X])).
More information about the erlang-questions
mailing list