gen_tcp:connect 使用主管时将关闭
gen_tcp:connect will close when using supervisor
我有一个简单的 gen_server 连接到一个 tcp 端口,当我 运行 gen_server 直接:
erl -noshell -s ttest start
它工作正常,但是当我 运行:
erl -noshell -s tt_sup start_link
连接会立即关闭,如果我取消链接主管就可以了:
erl -noshell -s tt_sup start_shell
我如何 运行 我简单的 gen_tcp:connect (gen_server) 与主管?
主管:
-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.
运行 -s
的进程在没有更多代码可执行时以 normal
退出。主管接收到该信号并且由于它来自其父级,它退出(不管它是 normal
),如 gen_server:terminate/2 中所述(supervisor
s 是 gen_server
s 与 trap_exit
活跃):
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.
我没有测试过您的代码,但是如果您将 process_flag(trap_exit, true)
添加到 gen_server
,您肯定会复制此行为。
我有一个简单的 gen_server 连接到一个 tcp 端口,当我 运行 gen_server 直接:
erl -noshell -s ttest start
它工作正常,但是当我 运行:
erl -noshell -s tt_sup start_link
连接会立即关闭,如果我取消链接主管就可以了:
erl -noshell -s tt_sup start_shell
我如何 运行 我简单的 gen_tcp:connect (gen_server) 与主管?
主管:
-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.
运行 -s
的进程在没有更多代码可执行时以 normal
退出。主管接收到该信号并且由于它来自其父级,它退出(不管它是 normal
),如 gen_server:terminate/2 中所述(supervisor
s 是 gen_server
s 与 trap_exit
活跃):
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.
我没有测试过您的代码,但是如果您将 process_flag(trap_exit, true)
添加到 gen_server
,您肯定会复制此行为。