Skip to content

Commit 9ed629c

Browse files
andymckjeffgrunewald
authored andcommitted
refactor socket mod to avoid restart when listener goes down
bump acceptor pool for more fixes upgrading acceptor_pool dep
1 parent 369f556 commit 9ed629c

File tree

3 files changed

+63
-37
lines changed

3 files changed

+63
-37
lines changed

rebar.config

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{erl_opts, [debug_info]}.
22

33
{deps, [
4-
{chatterbox, ".*", {git, "https://github.com/andymck/chatterbox", {branch, "andymck/fix-trailers-close-race-condition"}}},
4+
{chatterbox, ".*", {git, "https://github.com/novalabsxyz/chatterbox", {branch, "master"}}},
55
ctx,
6-
acceptor_pool,
7-
gproc]}.
6+
{acceptor_pool, {git, "https://github.com/novalabsxyz/acceptor_pool", {branch, "master"}}},
7+
gproc
8+
]}.
89

910
{grpc, [{protos, ["proto"]},
1011
{service_modules, [{'grpc.health.v1.Health', "grpcbox_health"},
@@ -49,7 +50,7 @@
4950
deprecated_function_calls, deprecated_functions]}.
5051

5152
{project_plugins, [covertool,
52-
{grpcbox_plugin, {git, "https://github.com/andymck/grpcbox_plugin.git",{branch, "master"}}},
53+
{grpcbox_plugin, {git, "https://github.com/novalabsxyz/grpcbox_plugin.git",{branch, "master"}}},
5354
rebar3_lint]}.
5455

5556
{cover_enabled, true}.

rebar.lock

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
{"1.2.0",
2-
[{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},0},
2+
[{<<"acceptor_pool">>,
3+
{git,"https://github.com/novalabsxyz/acceptor_pool",
4+
{ref,"56d676e00c11fd071a6bcc4059e3454960900af7"}},
5+
0},
36
{<<"chatterbox">>,
4-
{git,"https://github.com/andymck/chatterbox",
5-
{ref,"9055e611d509eec2f182bbf52a54ec821b17ac59"}},
7+
{git,"https://github.com/novalabsxyz/chatterbox",
8+
{ref,"cbfe6e46b273f1552b57685c9f6daf710473c609"}},
69
0},
710
{<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},0},
811
{<<"gproc">>,{pkg,<<"gproc">>,<<"0.8.0">>},0},
912
{<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.2.3">>},1}]}.
1013
[
1114
{pkg_hash,[
12-
{<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>},
1315
{<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>},
1416
{<<"gproc">>, <<"CEA02C578589C61E5341FCE149EA36CCEF236CC2ECAC8691FBA408E7EA77EC2F">>},
1517
{<<"hpack">>, <<"17670F83FF984AE6CD74B1C456EDDE906D27FF013740EE4D9EFAA4F1BF999633">>}]},
1618
{pkg_hash_ext,[
17-
{<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
1819
{<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>},
1920
{<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>},
2021
{<<"hpack">>, <<"06F580167C4B8B8A6429040DF36CC93BBA6D571FAEAEC1B28816523379CBB23A">>}]}

src/grpcbox_socket.erl

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,62 @@
1111
code_change/3,
1212
terminate/2]).
1313

14-
%% public api
14+
-record(state, {
15+
pool,
16+
listen_opts,
17+
pool_opts,
18+
socket,
19+
mref
20+
}).
1521

22+
%% public api
1623
start_link(Pool, ListenOpts, AcceptorOpts) ->
1724
gen_server:start_link(?MODULE, [Pool, ListenOpts, AcceptorOpts], []).
1825

1926
%% gen_server api
2027

2128
init([Pool, ListenOpts, PoolOpts]) ->
29+
{ok, #state{pool = Pool, pool_opts = PoolOpts, listen_opts = ListenOpts}, 0}.
30+
31+
handle_call(Req, _, State) ->
32+
{stop, {bad_call, Req}, State}.
33+
34+
handle_cast(Req, State) ->
35+
{stop, {bad_cast, Req}, State}.
36+
handle_info(timeout, State) ->
37+
case start_listener(State) of
38+
{ok, {Socket, MRef}} ->
39+
{noreply, State#state{socket = Socket, mref = MRef}};
40+
_ ->
41+
erlang:send_after(5000, self(), timeout),
42+
{noreply, State}
43+
end;
44+
handle_info({'DOWN', MRef, port, Socket, _Reason}, #state{mref = MRef, socket = Socket} = State) ->
45+
catch gen_tcp:close(Socket),
46+
erlang:send_after(5000, self(), timeout),
47+
{noreply, State};
48+
handle_info(_Msg, State) ->
49+
{noreply, State}.
50+
51+
code_change(_, State, _) ->
52+
{ok, State}.
53+
54+
terminate(_Reason, {Socket, MRef}) ->
55+
%% Socket may already be down but need to ensure it is closed to avoid
56+
%% eaddrinuse error on restart
57+
%% this takes care of that, unless of course this process is killed...
58+
case demonitor(MRef, [flush, info]) of
59+
true -> gen_tcp:close(Socket);
60+
false -> ok
61+
end.
62+
63+
%% ------------------------------------------------------------------
64+
%% Internal functions
65+
%% ------------------------------------------------------------------
66+
start_listener(#state{
67+
pool = Pool,
68+
listen_opts = ListenOpts,
69+
pool_opts = PoolOpts} = _State) ->
2270
Port = maps:get(port, ListenOpts, 8080),
2371
IPAddress = maps:get(ip, ListenOpts, {0, 0, 0, 0}),
2472
AcceptorPoolSize = maps:get(size, PoolOpts, 10),
@@ -27,8 +75,7 @@ init([Pool, ListenOpts, PoolOpts]) ->
2775
{reuseaddr, true},
2876
{backlog, 32768},
2977
{keepalive, true}]),
30-
%% Trapping exit so can close socket in terminate/2
31-
_ = process_flag(trap_exit, true),
78+
3279
Opts = [{active, false}, {mode, binary}, {packet, raw}, {ip, IPAddress} | SocketOpts],
3380
case gen_tcp:listen(Port, Opts) of
3481
{ok, Socket} ->
@@ -78,30 +125,7 @@ init([Pool, ListenOpts, PoolOpts]) ->
78125
socket_not_found ->
79126
noop
80127
end,
81-
{stop, eaddrinuse};
128+
{error, eaddrinuse};
82129
{error, Reason} ->
83-
{stop, Reason}
84-
end.
85-
86-
handle_call(Req, _, State) ->
87-
{stop, {bad_call, Req}, State}.
88-
89-
handle_cast(Req, State) ->
90-
{stop, {bad_cast, Req}, State}.
91-
92-
handle_info({'DOWN', MRef, port, Socket, Reason}, {Socket, MRef} = State) ->
93-
{stop, Reason, State};
94-
handle_info(_, State) ->
95-
{noreply, State}.
96-
97-
code_change(_, State, _) ->
98-
{ok, State}.
99-
100-
terminate(_Reason, {Socket, MRef}) ->
101-
%% Socket may already be down but need to ensure it is closed to avoid
102-
%% eaddrinuse error on restart
103-
%% this takes care of that, unless of course this process is killed...
104-
case demonitor(MRef, [flush, info]) of
105-
true -> gen_tcp:close(Socket);
106-
false -> ok
130+
{error, Reason}
107131
end.

0 commit comments

Comments
 (0)