Skip to content

Commit 100e7e1

Browse files
authored
Merge pull request #1730 from rabbitmq/rabbitmq-server-1711
Refactor listener startup error handling
2 parents 5e5d8da + 77bf5d6 commit 100e7e1

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

src/rabbit_networking.erl

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@
6868
-type protocol() :: atom().
6969
-type label() :: string().
7070

71-
-spec start_tcp_listener(listener_config(), integer()) -> 'ok'.
72-
-spec start_ssl_listener
73-
(listener_config(), rabbit_types:infos(), integer()) -> 'ok'.
71+
-spec start_tcp_listener(
72+
listener_config(), integer()) -> 'ok' | {'error', term()}.
73+
-spec start_ssl_listener(
74+
listener_config(), rabbit_types:infos(), integer()) -> 'ok' | {'error', term()}.
7475
-spec stop_tcp_listener(listener_config()) -> 'ok'.
7576
-spec active_listeners() -> [rabbit_types:listener()].
7677
-spec node_listeners(node()) -> [rabbit_types:listener()].
@@ -118,17 +119,35 @@
118119
boot() ->
119120
ok = record_distribution_listener(),
120121
_ = application:start(ranch),
121-
ok = boot_tcp(application:get_env(rabbit, num_tcp_acceptors, 10)),
122-
ok = boot_ssl(application:get_env(rabbit, num_ssl_acceptors, 1)),
122+
%% Failures will throw exceptions
123+
_ = boot_listeners(fun boot_tcp/1, application:get_env(rabbit, num_tcp_acceptors, 10), "TCP"),
124+
_ = boot_listeners(fun boot_tls/1, application:get_env(rabbit, num_ssl_acceptors, 10), "TLS"),
123125
_ = maybe_start_proxy_protocol(),
124126
ok.
125127

128+
boot_listeners(Fun, NumAcceptors, Type) ->
129+
case Fun(NumAcceptors) of
130+
ok ->
131+
ok;
132+
{error, {could_not_start_listener, Address, Port, Details}} = Error ->
133+
rabbit_log:error("Failed to start ~s listener [~s]:~p, error: ~p",
134+
[Type, Address, Port, Details]),
135+
throw(Error)
136+
end.
137+
126138
boot_tcp(NumAcceptors) ->
127139
{ok, TcpListeners} = application:get_env(tcp_listeners),
128-
[ok = start_tcp_listener(Listener, NumAcceptors) || Listener <- TcpListeners],
129-
ok.
140+
case lists:foldl(fun(Listener, ok) ->
141+
start_tcp_listener(Listener, NumAcceptors);
142+
(_Listener, Error) ->
143+
Error
144+
end,
145+
ok, TcpListeners) of
146+
ok -> ok;
147+
{error, _} = Error -> Error
148+
end.
130149

131-
boot_ssl(NumAcceptors) ->
150+
boot_tls(NumAcceptors) ->
132151
case application:get_env(ssl_listeners) of
133152
{ok, []} ->
134153
ok;
@@ -212,26 +231,36 @@ tcp_listener_spec(NamePrefix, {IPAddress, Port, Family}, SocketOpts,
212231
transient, infinity, supervisor, [tcp_listener_sup]}.
213232

214233
start_tcp_listener(Listener, NumAcceptors) ->
215-
start_listener(Listener, NumAcceptors, amqp, "TCP Listener", tcp_opts()).
234+
start_listener(Listener, NumAcceptors, amqp, "TCP listener", tcp_opts()).
216235

217236
start_ssl_listener(Listener, SslOpts, NumAcceptors) ->
218-
start_listener(Listener, NumAcceptors, 'amqp/ssl', "SSL Listener", tcp_opts() ++ SslOpts).
237+
start_listener(Listener, NumAcceptors, 'amqp/ssl', "TLS (SSL) listener", tcp_opts() ++ SslOpts).
238+
219239

240+
-spec start_listener(
241+
listener_config(), integer(), protocol(), label(), list()) -> 'ok' | {'error', term()}.
220242
start_listener(Listener, NumAcceptors, Protocol, Label, Opts) ->
221-
[start_listener0(Address, NumAcceptors, Protocol, Label, Opts) ||
222-
Address <- tcp_listener_addresses(Listener)],
223-
ok.
243+
lists:foldl(fun (Address, ok) ->
244+
start_listener0(Address, NumAcceptors, Protocol, Label, Opts);
245+
(_Address, {error, _} = Error) ->
246+
Error
247+
end, ok, tcp_listener_addresses(Listener)).
224248

225249
start_listener0(Address, NumAcceptors, Protocol, Label, Opts) ->
226250
Transport = transport(Protocol),
227251
Spec = tcp_listener_spec(rabbit_tcp_listener_sup, Address, Opts,
228252
Transport, rabbit_connection_sup, [], Protocol,
229253
NumAcceptors, Label),
230254
case supervisor:start_child(rabbit_sup, Spec) of
231-
{ok, _} -> ok;
232-
{error, {shutdown, _}} -> {IPAddress, Port, _Family} = Address,
233-
exit({could_not_start_tcp_listener,
234-
{rabbit_misc:ntoa(IPAddress), Port}})
255+
{ok, _} -> ok;
256+
{error, {{shutdown, {failed_to_start_child, _,
257+
{shutdown, {failed_to_start_child, _,
258+
{listen_error, _, PosixError}}}}}, _}} ->
259+
{IPAddress, Port, _Family} = Address,
260+
{error, {could_not_start_listener, rabbit_misc:ntoa(IPAddress), Port, PosixError}};
261+
{error, Other} ->
262+
{IPAddress, Port, _Family} = Address,
263+
{error, {could_not_start_listener, rabbit_misc:ntoa(IPAddress), Port, Other}}
235264
end.
236265

237266
transport(Protocol) ->

0 commit comments

Comments
 (0)