File 3441-Adjustments-for-the-net_ticker_spawn_options-kernel-.patch of Package erlang
From 9c2648e7983285f7f61964e973b7bd8063d1d1bd Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Sat, 12 Feb 2022 22:19:17 +0100
Subject: [PATCH 1/3] Adjustments for the net_ticker_spawn_options kernel
parameter
---
erts/doc/src/alt_dist.xml | 28 ++++++++++--
lib/kernel/doc/src/kernel_app.xml | 45 ++++++++++++-------
.../erl_uds_dist/src/erl_uds_dist.erl | 16 +------
.../gen_tcp_dist/src/gen_tcp_dist.erl | 4 +-
lib/kernel/src/dist_util.erl | 20 ++++++++-
lib/kernel/src/inet_tcp_dist.erl | 13 +-----
lib/kernel/test/erl_distribution_SUITE.erl | 43 ++++++++++++++----
lib/ssl/src/inet_tls_dist.erl | 11 +----
lib/ssl/src/ssl.app.src | 2 +-
9 files changed, 116 insertions(+), 66 deletions(-)
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index febfd8b130..c5ece5b456 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -314,8 +314,18 @@
<c>accept_connection/5</c> should spawn a process that will
perform the Erlang distribution handshake for the connection.
If the handshake successfully completes it should continue to
- function as a connection supervisor. This process
- should preferably execute on <c>max</c> priority.
+ function as a connection supervisor. This process should
+ preferably execute on <c>max</c> priority and should be linked
+ to the caller. The <c>dist_util:net_ticker_spawn_options()</c>
+ function can be called to get spawn options suitable for this process
+ which can be passed directly to
+ <seemfa marker="erts:erlang#spawn_opt/4"><c>erlang:spawn_opt/4</c></seemfa>.
+ <c>dist_util:net_ticker_spawn_options()</c> will by default return
+ <c>[link, {priority, max}]</c>, but allows the user to configure more
+ options using the
+ <seeapp marker="kernel:kernel_app#net_ticker_spawn_options"><c>net_ticker_spawn_options</c></seeapp>
+ kernel parameter. The process identifier of this process should be
+ returned.
</p>
<p>The arguments:</p>
<taglist>
@@ -380,8 +390,18 @@
<c>Node</c>. When connection has been established it should
perform the Erlang distribution handshake for the connection.
If the handshake successfully completes it should continue to
- function as a connection supervisor. This process
- should preferably execute on <c>max</c> priority.
+ function as a connection supervisor. This process should
+ preferably execute on <c>max</c> priority and should be linked
+ to the caller. The <c>dist_util:net_ticker_spawn_options()</c>
+ function can be called to get spawn options suitable for this process
+ which can be passed directly to
+ <seemfa marker="erts:erlang#spawn_opt/4"><c>erlang:spawn_opt/4</c></seemfa>.
+ <c>dist_util:net_ticker_spawn_options()</c> will by default return
+ <c>[link, {priority, max}]</c>, but allows the user to configure more
+ options using the
+ <seeapp marker="kernel:kernel_app#net_ticker_spawn_options"><c>net_ticker_spawn_options</c></seeapp>
+ kernel parameter. The process identifier of this process should be
+ returned.
</p>
<p>The arguments:</p>
<taglist>
diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml
index bc7ef2e973..905191202f 100644
--- a/lib/kernel/doc/src/kernel_app.xml
+++ b/lib/kernel/doc/src/kernel_app.xml
@@ -290,15 +290,6 @@
other distributed Erlang nodes.
See <seemfa marker="gen_tcp#connect/4"><c>gen_tcp:connect/4</c></seemfa>.</p>
</item>
- <tag><c>{net_ticker_spawn_options, Opts}</c></tag>
- <item>
- <marker id="net_ticker_spawn_options"></marker>
- <p>Defines a list of extra spawn options for dist_util:con_loop processes.
- When there is a large number of dist connections, setting up garbage collection
- options can be helpful to reduce memory usage. Default is [link, {priority, max}],
- and these two options cannot be changed.
- See <seemfa marker="erts:erlang#spawn_opt/2"><c>erlang:spawn_opt/2</c></seemfa>.</p>
- </item>
<tag><c>inet_parse_error_log = silent</c></tag>
<item>
<p>If set, no log events are issued when erroneous lines are
@@ -325,6 +316,35 @@
setup time, but rather each individual network operation during
the connection setup and handshake.</p>
</item>
+ <tag><marker id="net_ticker_spawn_options"/><c>net_ticker_spawn_options = Opts</c></tag>
+ <item>
+ <p>
+ Defines a list of extra spawn options for net ticker processes. There exist
+ one such process for each connection to another node. A net ticker process is
+ responsible for supervising the connection it is associated with. These
+ processes also execute the distribution handshake protocol when setting up
+ connections. When there is a large number of distribution connections,
+ setting up garbage collection options can be helpful to reduce memory usage.
+ Default is <c>[link, {priority, max}]</c>, and these two options cannot be
+ changed. The <c>monitor</c> and <c>{monitor, MonitorOpts}</c> options are
+ not allowed and will be dropped if present. See the documentation of the
+ <seemfa marker="erts:erlang#spawn_opt/4"><c>erlang:spawn_opt/4</c></seemfa>
+ BIF for information about valid options. If the <c>Opts</c> list is not
+ a proper list, or containing invalid options the setup of connections
+ will fail.
+ </p>
+ <p>
+ Note that the behavior described above is only true if the distribution
+ carrier protocol used is implemented as described in
+ <seeguide marker="erts:alt_dist#distribution_module">ERTS
+ User's Guide ➜ How to implement an Alternative Carrier
+ for the Erlang Distribution ➜ Distribution Module</seeguide> without
+ further alterations. The implementer of the distribution carrier protocol
+ used, may have chosen to ignore the <c>net_ticker_spawn_options</c> parameter
+ or altered its behavior. Currently all distribution modules shipped with OTP
+ do, however, behave as described above.
+ </p>
+ </item>
<tag><marker id="net_tickintensity"/><c>net_tickintensity = NetTickIntensity</c></tag>
<item>
<p><i>Net tick intensity</i> specifies how many ticks to send during a
diff --git a/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl b/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl
index e4ef56b606..d6310bdd19 100644
--- a/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl
+++ b/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl
@@ -432,7 +432,7 @@ accept_loop(Kernel, ListeningSocket) ->
accept_connection(AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
spawn_opt(?MODULE, accept_supervisor,
[self(), AcceptPid, DistCtrl, MyNode, Allowed, SetupTime],
- net_ticker_spawn_options()).
+ dist_util:net_ticker_spawn_options()).
accept_supervisor(Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
?trace("~p~n", [{?MODULE, accept_connection, self()}]),
@@ -472,18 +472,6 @@ accept_supervisor(Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
dist_util:handshake_other_started(HSData)
end.
-
-%% ---------------------------------------------------------------------
-%% Allow to set different spawn options for dist_util processes using
-%% the net_ticker_spawn_options configuration parameter. Default is
-%% [link, {priority, max}] and these two options cannot be changed.
-%% ---------------------------------------------------------------------
-net_ticker_spawn_options() ->
- Opts = application:get_env(kernel, net_ticker_spawn_options, []),
- Opts1 = [{priority, max} | proplists:delete(priority, Opts)],
- [link | proplists:delete(link, Opts1)].
-
-
%% ---------------------------------------------------------------------
%% Define common values of the handshake data record, defined in
%% kernel/include/dist_util.hrl
@@ -676,7 +664,7 @@ getopts(ListeningSocket, Options) ->
setup(Node, Type, MyNode, _LongOrShortNames, SetupTime) ->
spawn_opt(?MODULE, setup_supervisor,
[self(), Node, Type, MyNode, SetupTime],
- net_ticker_spawn_options()).
+ dist_util:net_ticker_spawn_options()).
setup_supervisor(Kernel, Node, Type, MyNode, SetupTime) ->
?trace("~p~n", [{?MODULE, setup, self(), Node}]),
diff --git a/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl b/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
index f73a622607..39fa664db7 100644
--- a/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
+++ b/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
@@ -183,7 +183,7 @@ flush_controller(Pid, Socket) ->
accept_connection(AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
spawn_opt(?MODULE, do_accept,
[self(), AcceptPid, DistCtrl, MyNode, Allowed, SetupTime],
- [link, {priority, max}]).
+ dist_util:net_ticker_spawn_options()).
do_accept(Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
?trace("~p~n",[{?MODULE, do_accept, self(), MyNode}]),
@@ -230,7 +230,7 @@ nodelay() ->
setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
spawn_opt(?MODULE, do_setup,
[self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
- [link, {priority, max}]).
+ dist_util:net_ticker_spawn_options()).
do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
?trace("~p~n",[{?MODULE, do_setup, self(), Node}]),
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index 832fd2d485..66540478cb 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -31,7 +31,8 @@
start_timer/1, setup_timer/2,
reset_timer/1, cancel_timer/1,
is_node_name/1, split_node/1, is_allowed/2,
- shutdown/3, shutdown/4]).
+ shutdown/3, shutdown/4,
+ net_ticker_spawn_options/0]).
-import(error_logger,[error_msg/2]).
@@ -1269,3 +1270,20 @@ cancel_timer(Timer) ->
unlink(Timer),
exit(Timer, shutdown).
+net_ticker_spawn_options() ->
+ Opts = application:get_env(kernel, net_ticker_spawn_options, []),
+ [link, {priority, max} | cleanup_net_ticker_spawn_options(Opts)].
+
+cleanup_net_ticker_spawn_options([]) ->
+ [];
+cleanup_net_ticker_spawn_options([link|Opts]) ->
+ cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([{priority, _}|Opts]) ->
+ cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([monitor|Opts]) ->
+ cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([{monitor, _}|Opts]) ->
+ cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([Opt|Opts]) ->
+ [Opt|cleanup_net_ticker_spawn_options(Opts)].
+
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index 621445923d..0102c5c677 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -208,7 +208,7 @@ accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
gen_accept_connection(Driver, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
spawn_opt(?MODULE, do_accept,
[Driver, self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
- net_ticker_spawn_options()).
+ dist_util:net_ticker_spawn_options()).
do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
receive
@@ -274,15 +274,6 @@ nodelay() ->
{nodelay, true}
end.
-
-% we may want different spawn options for dist_util processes
-
-net_ticker_spawn_options() ->
- Opts = application:get_env(kernel, net_ticker_spawn_options, []),
- Opts1 = [{priority, max} | proplists:delete(priority, Opts)],
- [link | proplists:delete(link, Opts1)].
-
-
%% ------------------------------------------------------------
%% Get remote information about a Socket.
%% ------------------------------------------------------------
@@ -312,7 +303,7 @@ setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
spawn_opt(?MODULE, do_setup,
[Driver, self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
- net_ticker_spawn_options()).
+ dist_util:net_ticker_spawn_options()).
do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
?trace("~p~n",[{inet_tcp_dist,self(),setup,Node}]),
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 8ec5e67abf..098af198db 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -1094,6 +1094,9 @@ get_socket_priorities() ->
%% check net_ticker_spawn_options
net_ticker_spawn_options(Config) when is_list(Config) ->
+ run_dist_configs(fun net_ticker_spawn_options/2, Config).
+
+net_ticker_spawn_options(DCfg, Config) when is_list(Config) ->
FullsweepString0 = "[{fullsweep_after,0}]",
FullsweepString =
case os:cmd("echo [{a,1}]") of
@@ -1107,16 +1110,16 @@ net_ticker_spawn_options(Config) when is_list(Config) ->
"-hidden "
"-kernel net_ticker_spawn_options "++FullsweepString,
{ok,Node1} =
- start_node("", net_ticker_spawn_options_1, InetDistOptions),
+ start_node(DCfg, net_ticker_spawn_options_1, InetDistOptions),
{ok,Node2} =
- start_node("", net_ticker_spawn_options_2, InetDistOptions),
+ start_node(DCfg, net_ticker_spawn_options_2, InetDistOptions),
%%
pong =
- rpc:call(Node1, net_adm, ping, [Node2]),
+ erpc:call(Node1, net_adm, ping, [Node2]),
FullsweepOptionNode1 =
- rpc:call(Node1, ?MODULE, get_net_ticker_fullsweep_option, [Node2]),
+ erpc:call(Node1, ?MODULE, get_net_ticker_fullsweep_option, [Node2]),
FullsweepOptionNode2 =
- rpc:call(Node2, ?MODULE, get_net_ticker_fullsweep_option, [Node1]),
+ erpc:call(Node2, ?MODULE, get_net_ticker_fullsweep_option, [Node1]),
io:format("FullsweepOptionNode1 = ~p", [FullsweepOptionNode1]),
io:format("FullsweepOptionNode2 = ~p", [FullsweepOptionNode2]),
0 = FullsweepOptionNode1,
@@ -1127,9 +1130,33 @@ net_ticker_spawn_options(Config) when is_list(Config) ->
ok.
get_net_ticker_fullsweep_option(Node) ->
- Port = proplists:get_value(Node, erlang:system_info(dist_ctrl)),
- {links, [DistUtilPid, _NetKernelPid]} = erlang:port_info(Port, links),
- {garbage_collection, GCOpts} = erlang:process_info(DistUtilPid, garbage_collection),
+ Links = case proplists:get_value(Node, erlang:system_info(dist_ctrl)) of
+ DistCtrl when is_port(DistCtrl) ->
+ {links, Ls} = erlang:port_info(DistCtrl, links),
+ Ls;
+ DistCtrl when is_pid(DistCtrl) ->
+ {links, Ls} = process_info(DistCtrl, links),
+ Ls
+ end,
+ Ticker = try
+ lists:foreach(
+ fun (Pid) when is_pid(Pid) ->
+ {current_stacktrace, Stk}
+ = process_info(Pid, current_stacktrace),
+ lists:foreach(
+ fun ({dist_util, con_loop, _, _}) ->
+ throw(Pid);
+ (_) ->
+ ok
+ end, Stk);
+ (_) ->
+ ok
+ end, Links),
+ error(no_ticker_found)
+ catch
+ throw:Pid when is_pid(Pid) -> Pid
+ end,
+ {garbage_collection, GCOpts} = erlang:process_info(Ticker, garbage_collection),
proplists:get_value(fullsweep_after, GCOpts).
diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index a19f0f2544..7e01ae4f71 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -440,7 +440,7 @@ gen_accept_connection(
Driver, AcceptPid, DistCtrl,
MyNode, Allowed, SetupTime, Kernel)
end,
- net_ticker_spawn_options())).
+ dist_util:net_ticker_spawn_options())).
do_accept(
_Driver, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime, Kernel) ->
@@ -539,7 +539,7 @@ gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
Kernel = self(),
monitor_pid(
spawn_opt(setup_fun(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime),
- net_ticker_spawn_options())).
+ dist_util:net_ticker_spawn_options())).
-spec setup_fun(_,_,_,_,_,_,_) -> fun(() -> no_return()).
setup_fun(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
@@ -807,13 +807,6 @@ nodelay() ->
end.
-% we may want different spawn options for dist_util processes
-
-net_ticker_spawn_options() ->
- Opts = application:get_env(kernel, net_ticker_spawn_options, []),
- Opts1 = [{priority, max} | proplists:delete(priority, Opts)],
- [link | proplists:delete(link, Opts1)].
-
get_ssl_options(Type) ->
try ets:lookup(ssl_dist_opts, Type) of
[{Type, Opts0}] ->
--
2.34.1