• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

emqx / esockd / 527

16 Sep 2025 07:26AM UTC coverage: 67.052% (+1.0%) from 66.039%
527

push

github

web-flow
Merge pull request #211 from JimMoen/fix-rate-limit-pause

fix: the next check start time should be `Now + Pasue`

2 of 2 new or added lines in 1 file covered. (100.0%)

228 existing lines in 13 files now uncovered.

696 of 1038 relevant lines covered (67.05%)

106.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.8
/src/esockd_sup.erl
1
%%--------------------------------------------------------------------
2
%% Copyright (c) 2020 EMQ Technologies Co., Ltd. All Rights Reserved.
3
%%
4
%% Licensed under the Apache License, Version 2.0 (the "License");
5
%% you may not use this file except in compliance with the License.
6
%% You may obtain a copy of the License at
7
%%
8
%%     http://www.apache.org/licenses/LICENSE-2.0
9
%%
10
%% Unless required by applicable law or agreed to in writing, software
11
%% distributed under the License is distributed on an "AS IS" BASIS,
12
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
%% See the License for the specific language governing permissions and
14
%% limitations under the License.
15
%%--------------------------------------------------------------------
16

17
-module(esockd_sup).
18

19
-behaviour(supervisor).
20

21
-export([start_link/0]).
22

23
-export([child_id/2]).
24

25
-export([ start_listener/4
26
        , stop_listener/2
27
        , restart_listener/2
28
        ]).
29

30
-export([ listeners/0
31
        , listener/1
32
        , listener_and_module/1
33
        ]).
34

35
-export([ child_spec/4
36
        , udp_child_spec/4
37
        , dtls_child_spec/4
38
        , start_child/1
39
        ]).
40

41
%% supervisor callback
42
-export([init/1]).
43

44
%%--------------------------------------------------------------------
45
%% API
46
%%--------------------------------------------------------------------
47

48
-spec(start_link() -> {ok, pid()} | ignore | {error, term()}).
49
start_link() ->
50
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
12✔
51

52
-spec(start_listener(atom(), esockd:listen_on(), [esockd:option()], esockd:mfargs())
53
      -> {ok, pid()} | {error, term()}).
54
start_listener(Proto, ListenOn, Opts, MFA) ->
55
    start_child(child_spec(Proto, ListenOn, Opts, MFA)).
84✔
56

57
-spec(child_spec(atom(), esockd:listen_on(), [esockd:option()], esockd:mfargs())
58
      -> supervisor:child_spec()).
59
child_spec(Proto, ListenOn, Opts, MFA) when is_atom(Proto) ->
60
    #{id => child_id(Proto, ListenOn),
87✔
61
      start => {esockd_listener_sup, start_link, [tcp, Proto, ListenOn, Opts, MFA]},
62
      restart => transient,
63
      shutdown => infinity,
64
      type => supervisor,
65
      modules => [esockd_listener_sup]}.
66

67
-spec(udp_child_spec(atom(), esockd:listen_on(), [esockd:option()], esockd:mfargs())
68
      -> supervisor:child_spec()).
69
udp_child_spec(Proto, Port, Opts, MFA) when is_atom(Proto) ->
70
    #{id => child_id(Proto, Port),
24✔
71
      start => {esockd_udp, server, [Proto, Port, Opts, MFA]},
72
      restart => transient,
73
      shutdown => 5000,
74
      type => worker,
75
      modules => [esockd_udp]}.
76

77
-spec(dtls_child_spec(atom(), esockd:listen_on(), [esockd:option()], esockd:mfargs())
78
      -> supervisor:child_spec()).
79
dtls_child_spec(Proto, Port, Opts, MFA) when is_atom(Proto) ->
80
    #{id => child_id(Proto, Port),
33✔
81
      start => {esockd_listener_sup, start_link, [dtls, Proto, Port, Opts, MFA]},
82
      restart => transient,
83
      shutdown => infinity,
84
      type => supervisor,
85
      modules => [esockd_listener_sup]}.
86

87
-spec(start_child(supervisor:child_spec()) -> {ok, pid()} | {error, term()}).
88
start_child(ChildSpec) ->
89
        supervisor:start_child(?MODULE, ChildSpec).
135✔
90

91
-spec(stop_listener(atom(), esockd:listen_on()) -> ok | {error, term()}).
92
stop_listener(Proto, ListenOn) ->
93
    case match_listeners(Proto, ListenOn) of
135✔
UNCOV
94
        [] -> {error, not_found};
×
95
        Listeners ->
96
            return_ok_or_error([terminate_and_delete(ChildId) || ChildId <- Listeners])
135✔
97
    end.
98

99
terminate_and_delete(ChildId) ->
100
        case supervisor:terminate_child(?MODULE, ChildId) of
135✔
101
        ok    -> supervisor:delete_child(?MODULE, ChildId);
135✔
UNCOV
102
        Error -> Error
×
103
        end.
104

105
-spec(listeners() -> [{term(), pid()}]).
106
listeners() ->
107
    [{Id, Pid} || {{listener_sup, Id}, Pid, _Type, _} <- supervisor:which_children(?MODULE)].
6✔
108

109
-spec(listener({atom(), esockd:listen_on()}) -> pid()).
110
listener({Proto, ListenOn}) ->
111
    ChildId = child_id(Proto, ListenOn),
6✔
112
    case [Pid || {Id, Pid, _Type, _} <- supervisor:which_children(?MODULE), Id =:= ChildId] of
6✔
113
        [] -> error(not_found);
3✔
114
        L  -> hd(L)
3✔
115
    end.
116

117
-spec(listener_and_module({atom(), esockd:listen_on()})
118
     -> undefined
119
      | {ListenerSup :: pid(), Mod :: esockd_listener_sup | esockd_udp}).
120
listener_and_module({Proto, ListenOn}) ->
121
    ChildId = child_id(Proto, ListenOn),
165✔
122
    case [{Pid, Mod} || {Id, Pid, _Type, [Mod|_]} <- supervisor:which_children(?MODULE), Id =:= ChildId] of
165✔
123
        [] -> undefined;
18✔
124
        L  -> hd(L)
147✔
125
    end.
126

127
-spec(restart_listener(atom(), esockd:listen_on()) -> ok | {error, term()}).
128
restart_listener(Proto, ListenOn) ->
129
    case match_listeners(Proto, ListenOn) of
9✔
130
        [] -> {error, not_found};
3✔
131
        Listeners ->
132
            return_ok_or_error([terminate_and_restart(ChildId) || ChildId <- Listeners])
6✔
133
    end.
134

135
terminate_and_restart(ChildId) ->
136
    case supervisor:terminate_child(?MODULE, ChildId) of
6✔
137
        ok    -> supervisor:restart_child(?MODULE, ChildId);
6✔
UNCOV
138
        Error -> Error
×
139
    end.
140

141
match_listeners(Proto, ListenOn) ->
142
    [ChildId || {ChildId, _Pid, _Type, _} <- supervisor:which_children(?MODULE),
144✔
143
                match_listener(Proto, ListenOn, ChildId)].
432✔
144

145
match_listener(Proto, ListenOn, {listener_sup, {Proto, ListenOn}}) ->
146
    true;
141✔
147
match_listener(Proto, Port, {listener_sup, {Proto, {_IP, Port}}}) ->
UNCOV
148
    true;
×
149
match_listener(_Proto, _ListenOn, _ChildId) ->
150
    false.
291✔
151

152
child_id(Proto, ListenOn) ->
153
    {listener_sup, {Proto, ListenOn}}.
315✔
154

155
return_ok_or_error([]) -> ok;
141✔
156
return_ok_or_error([ok|Results]) ->
157
    return_ok_or_error(Results);
135✔
158
return_ok_or_error([{ok, _Pid}|Results]) ->
159
    return_ok_or_error(Results);
6✔
160
return_ok_or_error([{error, Reason}|_]) ->
UNCOV
161
    {error, Reason}.
×
162

163
%%--------------------------------------------------------------------
164
%% Supervisor callbacks
165
%%--------------------------------------------------------------------
166

167
init([]) ->
168
    SupFlags = #{strategy => one_for_one,
12✔
169
                 intensity => 10,
170
                 period => 100
171
                },
172
    Limiter = #{id => esockd_limiter,
12✔
173
                start => {esockd_limiter, start_link, []},
174
                restart => permanent,
175
                shutdown => 5000,
176
                type => worker,
177
                modules => [esockd_limiter]
178
               },
179
    Server = #{id => esockd_server,
12✔
180
               start => {esockd_server, start_link, []},
181
               restart => permanent,
182
               shutdown => 5000,
183
               type => worker,
184
               modules => [esockd_server]
185
              },
186
    {ok, {SupFlags, [Limiter, Server]}}.
12✔
187

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc