I have a simple gen_server which connects to a tcp port, when I run gen_server directly:erl -noshell -s ttest start
it works fine, But when I run:erl -noshell -s tt_sup start_link
the connection will be closed instantly, It will work if I unlink the supervisor:erl -noshell -s tt_sup start_shell
How could I run my simple gen_tcp:connect (gen_server) with supervisor ?
Supervisor :
-module(tt_sup).
-behaviour(supervisor).
-export([init/1, start_link/0, start_shell/0]).
start_link() ->
io:format("Supervisor started with PID~p~n", [self()]),
{ok, Pid} = supervisor:start_link(tt_sup, []),
io:format("Supervisor PID=~p~n", [Pid]),
{ok, Pid}.
start_shell() ->
io:format("Supervisor started with PID~p~n", [self()]),
{ok, Pid} = supervisor:start_link(tt_sup, []),
io:format("Supervisor PID=~p~n", [Pid]),
unlink(Pid),
{ok, Pid}.
init(_Args) ->
SupFlags = #{strategy => one_for_one},
Child = [#{id => ttest, start => {ttest, start, []},
restart => permanent, shutdown => brutal_kill,
type => worker, modules => [ttest]}],
{ok, {SupFlags, Child}}.
gen_server:
-module(ttest).
-export([start/0,init/1,handle_cast/2,handle_call/3,handle_info/2,terminate/2,connect/1]).
-behaviour(gen_server).
start() ->
io:format("gen_server start id is ~p~n",[self()]),
{ok,Pid} = gen_server:start_link({local,ttest},ttest,[],[]),
io:format("gen_server id is ~p~n",[Pid]),
connect(Pid),
{ok,Pid}.
init(_Args) ->
io:format("init id is ~p~n",[self()]),
{ok,[]}.
handle_call({tcp,Socket,Bin},_From,States) ->
{reply,States,States}.
handle_info({tcp,Socket,Bin},States) ->
io:format("got info msg"),
{noreply,States}.
handle_cast({send,Msg},States) ->
{reply,States}.
connect(I) ->
io:format("connect id is ~p~n",[self()]),
{ok,Socket} =gen_tcp:connect("localhost",6000,[binary,{active,true}]),
gen_tcp:controlling_process(Socket,I).
terminate(shutdown, State) ->
io:format("terminating"),
ok.
1条答案
按热度按时间toiithl61#
The process that runs the
-s
exits withnormal
when it has no more code to execute. The supervisor receives that signal and since it's from its parent, it exits (regardless of it beingnormal
), as explained in gen_server:terminate/2 (supervisor
s aregen_server
s withtrap_exit
active):Even if the gen_server process is not part of a supervision tree, this function is called if it receives an 'EXIT' message from its parent. Reason is the same as in the 'EXIT' message.
I haven't tested your code, but if you add a
process_flag(trap_exit, true)
to yourgen_server
, you'll surely replicate this behaviour.