From dd0baa002cf09286f5d80e046e8c8611f9e20d10 Mon Sep 17 00:00:00 2001 From: Tom Briden Date: Fri, 29 May 2015 10:40:34 +0100 Subject: Honour dist_nodelay socket option in tls_dist proxy If a plaintext cluster has nodelay=1 then so should the tls cluster; significant performance issues have been seen when nodelay isn't set --- lib/ssl/src/ssl_tls_dist_proxy.erl | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/ssl/src/ssl_tls_dist_proxy.erl b/lib/ssl/src/ssl_tls_dist_proxy.erl index a22af6b960..c5e473f923 100644 --- a/lib/ssl/src/ssl_tls_dist_proxy.erl +++ b/lib/ssl/src/ssl_tls_dist_proxy.erl @@ -133,6 +133,7 @@ accept_loop(Proxy, erts = Type, Listen, Extra) -> Extra ! {accept,self(),Socket,inet,proxy}, receive {_Kernel, controller, Pid} -> + inet:setopts(Socket, [nodelay()]), ok = gen_tcp:controlling_process(Socket, Pid), flush_old_controller(Pid, Socket), Pid ! {self(), controller}; @@ -166,7 +167,7 @@ accept_loop(Proxy, world = Type, Listen, Extra) -> accept_loop(Proxy, Type, Listen, Extra). try_connect(Port) -> - case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {packet,?PPRE}]) of + case gen_tcp:connect({127,0,0,1}, Port, [{active, false}, {packet,?PPRE}, nodelay()]) of R = {ok, _S} -> R; {error, _R} -> @@ -176,7 +177,7 @@ try_connect(Port) -> setup_proxy(Ip, Port, Parent) -> process_flag(trap_exit, true), Opts = get_ssl_options(client), - case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}] ++ Opts) of + case ssl:connect(Ip, Port, [{active, true}, binary, {packet,?PPRE}, nodelay()] ++ Opts) of {ok, World} -> {ok, ErtsL} = gen_tcp:listen(0, [{active, true}, {ip, {127,0,0,1}}, binary, {packet,?PPRE}]), {ok, #net_address{address={_,LPort}}} = get_tcp_address(ErtsL), @@ -192,25 +193,41 @@ setup_proxy(Ip, Port, Parent) -> Parent ! {self(), Err} end. + +%% we may not always want the nodelay behaviour +%% %% for performance reasons + +nodelay() -> + case application:get_env(kernel, dist_nodelay) of + undefined -> + {nodelay, true}; + {ok, true} -> + {nodelay, true}; + {ok, false} -> + {nodelay, false}; + _ -> + {nodelay, true} + end. + setup_connection(World, ErtsListen) -> process_flag(trap_exit, true), {ok, TcpAddress} = get_tcp_address(ErtsListen), {_Addr,Port} = TcpAddress#net_address.address, - {ok, Erts} = gen_tcp:connect({127,0,0,1}, Port, [{active, true}, binary, {packet,?PPRE}]), - ssl:setopts(World, [{active,true}, {packet,?PPRE}]), + {ok, Erts} = gen_tcp:connect({127,0,0,1}, Port, [{active, true}, binary, {packet,?PPRE}, nodelay()]), + ssl:setopts(World, [{active,true}, {packet,?PPRE}, nodelay()]), loop_conn_setup(World, Erts). loop_conn_setup(World, Erts) -> receive {ssl, World, Data = <<$a, _/binary>>} -> gen_tcp:send(Erts, Data), - ssl:setopts(World, [{packet,?PPOST}]), - inet:setopts(Erts, [{packet,?PPOST}]), + ssl:setopts(World, [{packet,?PPOST}, nodelay()]), + inet:setopts(Erts, [{packet,?PPOST}, nodelay()]), loop_conn(World, Erts); {tcp, Erts, Data = <<$a, _/binary>>} -> ssl:send(World, Data), - ssl:setopts(World, [{packet,?PPOST}]), - inet:setopts(Erts, [{packet,?PPOST}]), + ssl:setopts(World, [{packet,?PPOST}, nodelay()]), + inet:setopts(Erts, [{packet,?PPOST}, nodelay()]), loop_conn(World, Erts); {ssl, World, Data = <<_, _/binary>>} -> gen_tcp:send(Erts, Data), -- cgit v1.2.3 From d5ce9036c629939cd979a03ace1b0107c23a9d78 Mon Sep 17 00:00:00 2001 From: Magnus Henoch Date: Fri, 13 Nov 2015 16:50:16 +0000 Subject: Add test for dist_nodelay option Run the 'basic' test with dist_nodelay set to false. --- lib/ssl/test/ssl_dist_SUITE.erl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl index 1a1b2af8d4..a76fa03d33 100644 --- a/lib/ssl/test/ssl_dist_SUITE.erl +++ b/lib/ssl/test/ssl_dist_SUITE.erl @@ -43,7 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [basic, payload, plain_options, plain_verify_options]. + [basic, payload, plain_options, plain_verify_options, nodelay_option]. groups() -> []. @@ -255,6 +255,17 @@ plain_verify_options(Config) when is_list(Config) -> stop_ssl_node(NH1), stop_ssl_node(NH2), success(Config). +%%-------------------------------------------------------------------- +nodelay_option() -> + [{doc,"Test specifying dist_nodelay option"}]. +nodelay_option(Config) -> + try + %% The default is 'true', so try setting it to 'false'. + application:set_env(kernel, dist_nodelay, false), + basic(Config) + after + application:unset_env(kernel, dist_nodelay) + end. %%-------------------------------------------------------------------- %%% Internal functions ----------------------------------------------- -- cgit v1.2.3