aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj.uhlig <[email protected]>2018-05-04 16:23:27 +0200
committerLoïc Hoguin <[email protected]>2018-05-16 17:16:56 +0200
commit963f53942f1106771e91a018ac9ad46e3bc6a777 (patch)
tree6f733090ec39b55616b2ccdea266090dbfb8b365
parent16762abdcffa53834d44e22eb4d26ef699c89fc2 (diff)
downloadranch-963f53942f1106771e91a018ac9ad46e3bc6a777.tar.gz
ranch-963f53942f1106771e91a018ac9ad46e3bc6a777.tar.bz2
ranch-963f53942f1106771e91a018ac9ad46e3bc6a777.zip
Ensure listener restart with changed TransOpts
-rw-r--r--src/ranch_conns_sup.erl24
-rw-r--r--src/ranch_listener_sup.erl9
-rw-r--r--src/ranch_server.erl8
-rw-r--r--test/acceptor_SUITE.erl38
-rw-r--r--test/ranch_ct_hook.erl5
5 files changed, 63 insertions, 21 deletions
diff --git a/src/ranch_conns_sup.erl b/src/ranch_conns_sup.erl
index 6a2336f..812a6c3 100644
--- a/src/ranch_conns_sup.erl
+++ b/src/ranch_conns_sup.erl
@@ -18,12 +18,12 @@
-module(ranch_conns_sup).
%% API.
--export([start_link/6]).
+-export([start_link/3]).
-export([start_protocol/2]).
-export([active_connections/1]).
%% Supervisor internals.
--export([init/7]).
+-export([init/4]).
-export([system_continue/3]).
-export([system_terminate/4]).
-export([system_code_change/4]).
@@ -45,11 +45,10 @@
%% API.
--spec start_link(ranch:ref(), conn_type(), shutdown(), module(),
- timeout(), module()) -> {ok, pid()}.
-start_link(Ref, ConnType, Shutdown, Transport, AckTimeout, Protocol) ->
+-spec start_link(ranch:ref(), module(), module()) -> {ok, pid()}.
+start_link(Ref, Transport, Protocol) ->
proc_lib:start_link(?MODULE, init,
- [self(), Ref, ConnType, Shutdown, Transport, AckTimeout, Protocol]).
+ [self(), Ref, Transport, Protocol]).
%% We can safely assume we are on the same node as the supervisor.
%%
@@ -94,17 +93,20 @@ active_connections(SupPid) ->
%% Supervisor internals.
--spec init(pid(), ranch:ref(), conn_type(), shutdown(),
- module(), timeout(), module()) -> no_return().
-init(Parent, Ref, ConnType, Shutdown, Transport, AckTimeout, Protocol) ->
+-spec init(pid(), ranch:ref(), module(), module()) -> no_return().
+init(Parent, Ref, Transport, Protocol) ->
process_flag(trap_exit, true),
ok = ranch_server:set_connections_sup(Ref, self()),
MaxConns = ranch_server:get_max_connections(Ref),
- Opts = ranch_server:get_protocol_options(Ref),
+ TransOpts = ranch_server:get_transport_options(Ref),
+ ConnType = proplists:get_value(connection_type, TransOpts, worker),
+ Shutdown = proplists:get_value(shutdown, TransOpts, 5000),
+ AckTimeout = proplists:get_value(ack_timeout, TransOpts, 5000),
+ ProtoOpts = ranch_server:get_protocol_options(Ref),
ok = proc_lib:init_ack(Parent, {ok, self()}),
loop(#state{parent=Parent, ref=Ref, conn_type=ConnType,
shutdown=Shutdown, transport=Transport, protocol=Protocol,
- opts=Opts, ack_timeout=AckTimeout, max_conns=MaxConns}, 0, 0, []).
+ opts=ProtoOpts, ack_timeout=AckTimeout, max_conns=MaxConns}, 0, 0, []).
loop(State=#state{parent=Parent, ref=Ref, conn_type=ConnType,
transport=Transport, protocol=Protocol, opts=Opts,
diff --git a/src/ranch_listener_sup.erl b/src/ranch_listener_sup.erl
index 502df44..bd4ccc5 100644
--- a/src/ranch_listener_sup.erl
+++ b/src/ranch_listener_sup.erl
@@ -25,17 +25,14 @@ start_link(Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts) ->
ranch_server:set_new_listener_opts(Ref, MaxConns, TransOpts, ProtoOpts,
[Ref, NumAcceptors, Transport, TransOpts, Protocol, ProtoOpts]),
supervisor:start_link(?MODULE, {
- Ref, NumAcceptors, Transport, TransOpts, Protocol
+ Ref, NumAcceptors, Transport, Protocol
}).
-init({Ref, NumAcceptors, Transport, TransOpts, Protocol}) ->
+init({Ref, NumAcceptors, Transport, Protocol}) ->
ok = ranch_server:set_listener_sup(Ref, self()),
- AckTimeout = proplists:get_value(ack_timeout, TransOpts, 5000),
- ConnType = proplists:get_value(connection_type, TransOpts, worker),
- Shutdown = proplists:get_value(shutdown, TransOpts, 5000),
ChildSpecs = [
{ranch_conns_sup, {ranch_conns_sup, start_link,
- [Ref, ConnType, Shutdown, Transport, AckTimeout, Protocol]},
+ [Ref, Transport, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup]},
{ranch_acceptors_sup, {ranch_acceptors_sup, start_link,
[Ref, NumAcceptors, Transport]},
diff --git a/src/ranch_server.erl b/src/ranch_server.erl
index 80f82d6..015c9f9 100644
--- a/src/ranch_server.erl
+++ b/src/ranch_server.erl
@@ -156,10 +156,10 @@ init([]) ->
{ok, #state{monitors=ConnMonitors++ListenerMonitors}}.
handle_call({set_new_listener_opts, Ref, MaxConns, TransOpts, ProtoOpts, StartArgs}, _, State) ->
- ets:insert(?TAB, {{max_conns, Ref}, MaxConns}),
- ets:insert(?TAB, {{trans_opts, Ref}, TransOpts}),
- ets:insert(?TAB, {{proto_opts, Ref}, ProtoOpts}),
- ets:insert(?TAB, {{listener_start_args, Ref}, StartArgs}),
+ ets:insert_new(?TAB, {{max_conns, Ref}, MaxConns}),
+ ets:insert_new(?TAB, {{trans_opts, Ref}, TransOpts}),
+ ets:insert_new(?TAB, {{proto_opts, Ref}, ProtoOpts}),
+ ets:insert_new(?TAB, {{listener_start_args, Ref}, StartArgs}),
{reply, ok, State};
handle_call({set_connections_sup, Ref, Pid}, _,
State=#state{monitors=Monitors}) ->
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index e441b51..4918642 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -62,6 +62,7 @@ groups() ->
]}, {supervisor, [
connection_type_supervisor,
connection_type_supervisor_separate_from_connection,
+ supervisor_changed_options_restart,
supervisor_clean_child_restart,
supervisor_clean_conns_sup_restart,
supervisor_clean_restart,
@@ -799,6 +800,36 @@ connection_type_supervisor_separate_from_connection(_) ->
{'EXIT', _} = begin catch ranch:get_port(Name) end,
ok.
+supervisor_changed_options_restart(_) ->
+ doc("Ensure that a listener is restarted with changed transport options."),
+ Name = name(),
+ %% Start a listener using send_timeout as option change marker.
+ {ok, ListenerSupPid1} = ranch:start_listener(Name,
+ ranch_tcp, [{send_timeout, 300000}],
+ echo_protocol, []),
+ %% Ensure send_timeout is really set to initial value.
+ {ok, [{send_timeout, 300000}]}
+ = inet:getopts(do_get_listener_socket(ListenerSupPid1), [send_timeout]),
+ %% Change send_timeout option.
+ ok = ranch:suspend_listener(Name),
+ ok = ranch:set_transport_options(Name, [{send_timeout, 300001}]),
+ ok = ranch:resume_listener(Name),
+ %% Ensure send_timeout is really set to the changed value.
+ {ok, [{send_timeout, 300001}]}
+ = inet:getopts(do_get_listener_socket(ListenerSupPid1), [send_timeout]),
+ %% Crash the listener_sup process, allow a short time for restart to succeed.
+ exit(ListenerSupPid1, kill),
+ timer:sleep(1000),
+ %% Obtain pid of restarted listener_sup process.
+ [ListenerSupPid2] = [Pid || {{ranch_listener_sup, Ref}, Pid, supervisor, _}
+ <- supervisor:which_children(ranch_sup), Ref =:= Name],
+ %% Ensure send_timeout is still set to the changed value.
+ {ok, [{send_timeout, 300001}]}
+ = inet:getopts(do_get_listener_socket(ListenerSupPid2), [send_timeout]),
+ ok = ranch:stop_listener(Name),
+ {'EXIT', _} = begin catch ranch:get_port(Name) end,
+ ok.
+
supervisor_clean_child_restart(Config) ->
case code:is_module_native(?MODULE) of
true -> doc("This test uses tracing and is not compatible with native code.");
@@ -1034,3 +1065,10 @@ clean_traces() ->
after 0 ->
ok
end.
+
+do_get_listener_socket(ListenerSupPid) ->
+ [AcceptorsSupPid] = [Pid || {ranch_acceptors_sup, Pid, supervisor, _}
+ <- supervisor:which_children(ListenerSupPid)],
+ {links, Links} = erlang:process_info(AcceptorsSupPid, links),
+ [LSocket] = [P || P <- Links, is_port(P)],
+ LSocket.
diff --git a/test/ranch_ct_hook.erl b/test/ranch_ct_hook.erl
index 183cdf5..07f89df 100644
--- a/test/ranch_ct_hook.erl
+++ b/test/ranch_ct_hook.erl
@@ -17,6 +17,11 @@
-export([init/2]).
init(_, _) ->
+ %% Allow a more relaxed restart intensity because
+ %% some tests will cause quick restarts of several
+ %% ranch_sup children.
+ application:set_env(ranch, ranch_sup_intensity, 10),
+ application:set_env(ranch, ranch_sup_period, 1),
ct_helper:start([ranch]),
ct_helper:make_certs_in_ets(),
error_logger:add_report_handler(ct_helper_error_h),