1 |
|
%% @doc Manage starting and stopping of configured listeners |
2 |
|
|
3 |
|
-module(mongoose_listener). |
4 |
|
|
5 |
|
-include("mongoose.hrl"). |
6 |
|
|
7 |
|
%% Only for tests |
8 |
|
-export([start_listener/1, stop_listener/1]). |
9 |
|
-ignore_xref([start_listener/1, stop_listener/1]). |
10 |
|
|
11 |
|
%% API |
12 |
|
-export([start/0, stop/0]). |
13 |
|
|
14 |
|
-callback start_listener(options()) -> ok. |
15 |
|
|
16 |
|
-type options() :: #{port := inet:port_number(), |
17 |
|
ip_tuple := inet:ip_address(), |
18 |
|
ip_address := string(), |
19 |
|
ip_version := 4 | 6, |
20 |
|
proto := proto(), |
21 |
|
any() => any()}. |
22 |
|
-type id() :: {inet:port_number(), inet:ip_address(), proto()}. |
23 |
|
-type proto() :: tcp. |
24 |
|
|
25 |
|
-export_type([options/0, id/0, proto/0]). |
26 |
|
|
27 |
|
%% API |
28 |
|
|
29 |
|
start() -> |
30 |
33 |
lists:foreach(fun start_listener/1, mongoose_config:get_opt(listen)). |
31 |
|
|
32 |
|
stop() -> |
33 |
33 |
lists:foreach(fun stop_listener/1, mongoose_config:get_opt(listen)). |
34 |
|
|
35 |
|
%% Internal functions |
36 |
|
|
37 |
|
start_listener(Opts = #{module := Module}) -> |
38 |
535 |
try |
39 |
535 |
Module:start_listener(Opts) % This function should call mongoose_listener_sup:start_child/1 |
40 |
|
catch |
41 |
|
Class:Reason:Stacktrace -> |
42 |
:-( |
?LOG_CRITICAL(#{what => listener_failed_to_start, |
43 |
|
text => <<"Failed to start a listener">>, |
44 |
|
module => Module, opts => Opts, |
45 |
:-( |
class => Class, reason => Reason, stacktrace => Stacktrace}), |
46 |
:-( |
erlang:raise(Class, Reason, Stacktrace) |
47 |
|
end. |
48 |
|
|
49 |
|
stop_listener(Opts) -> |
50 |
535 |
ListenerId = mongoose_listener_config:listener_id(Opts), |
51 |
535 |
supervisor:terminate_child(mongoose_listener_sup, ListenerId), |
52 |
535 |
supervisor:delete_child(mongoose_listener_sup, ListenerId). |