Skip to content

Commit 69de6f1

Browse files
authored
Merge pull request #259 from qzhuyan/dev/william/conn-count
feat(listener): count connections under listener
2 parents 5427196 + e0c72c7 commit 69de6f1

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

src/quicer_listener.erl

+18-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
unlock/2,
2727
reload/2,
2828
reload/3,
29-
get_handle/2
29+
get_handle/2,
30+
count_conns/1
3031
]).
3132

3233
%% gen_server callbacks
@@ -107,6 +108,11 @@ reload(Pid, ListenOn, NewConf) ->
107108
get_handle(Pid, Timeout) ->
108109
gen_server:call(Pid, get_handle, Timeout).
109110

111+
%% @doc count accepted but not yet closed connections
112+
-spec count_conns(pid()) -> non_neg_integer().
113+
count_conns(Pid) ->
114+
gen_server:call(Pid, count_conns, infinity).
115+
110116
%%%===================================================================
111117
%%% gen_server callbacks
112118
%%%===================================================================
@@ -173,6 +179,17 @@ handle_call({reload, NewConf}, _From, State) ->
173179
handle_call({reload, NewListenOn, NewConf}, _From, State) ->
174180
{Res, NewState} = do_reload(NewListenOn, NewConf, State),
175181
{reply, Res, NewState};
182+
handle_call(
183+
count_conns,
184+
_From,
185+
#state{
186+
conn_sup = ConnSup,
187+
opts = #{conn_acceptors := NoAcceptors}
188+
} =
189+
State
190+
) ->
191+
ConnPids = supervisor:which_children(ConnSup),
192+
{reply, length(ConnPids) - NoAcceptors, State};
176193
handle_call(Request, _From, State) ->
177194
Reply = {error, {unimpl, Request}},
178195
{reply, Reply, State}.

test/quicer_listener_SUITE.erl

+66
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,72 @@ tc_get_listener_owner(Config) ->
953953
?assertEqual({ok, self()}, quicer:get_listener_owner(L)),
954954
quicer:close_listener(L).
955955

956+
tc_count_conns(Config) ->
957+
Port0 = select_port(),
958+
Port1 = select_port(),
959+
ServerConnCallback = example_server_connection,
960+
ServerStreamCallback = example_server_stream,
961+
ListenerOpts = [
962+
{conn_acceptors, 32},
963+
{peer_bidi_stream_count, 0},
964+
{peer_unidi_stream_count, 2}
965+
| default_listen_opts(Config)
966+
],
967+
ConnectionOpts = [
968+
{conn_callback, ServerConnCallback},
969+
{stream_acceptors, 2}
970+
| default_conn_opts()
971+
],
972+
StreamOpts = [
973+
{stream_callback, ServerStreamCallback}
974+
| default_stream_opts()
975+
],
976+
Options = {ListenerOpts, ConnectionOpts, StreamOpts},
977+
978+
%% GIVEN: Two QUIC listeners
979+
{ok, QuicApp} = quicer:spawn_listener(sample, Port0, Options),
980+
981+
{ok, QuicApp2} = quicer:spawn_listener(sample2, Port1, Options),
982+
983+
ClientConnOpts = default_conn_opts_verify(Config, ca),
984+
985+
%% WHEN: a client is connected to the first listener
986+
{ok, ClientConnPid} = example_client_connection:start_link(
987+
"localhost",
988+
Port0,
989+
{ClientConnOpts, default_stream_opts()}
990+
),
991+
#{is_resumed := false} = snabbkaffe:retry(
992+
50,
993+
20,
994+
fun() ->
995+
#{is_resumed := false} = quicer_connection:get_cb_state(ClientConnPid)
996+
end
997+
),
998+
999+
%% Then the first listener has one connection and other has none
1000+
?assertEqual({1, 0}, {
1001+
quicer_listener:count_conns(QuicApp), quicer_listener:count_conns(QuicApp2)
1002+
}),
1003+
1004+
%% WHEN: client is stopped
1005+
gen_server:stop(ClientConnPid),
1006+
1007+
%% THEN: both listeners have no connections
1008+
{0, 0} = snabbkaffe:retry(
1009+
10,
1010+
100,
1011+
fun() ->
1012+
{0, 0} =
1013+
{quicer_listener:count_conns(QuicApp), quicer_listener:count_conns(QuicApp2)}
1014+
end
1015+
),
1016+
1017+
quicer:terminate_listener(sample),
1018+
quicer:terminate_listener(sample2).
1019+
1020+
%%% Helpers
1021+
9561022
select_port() ->
9571023
Port = select_free_port(quic),
9581024
timer:sleep(100),

0 commit comments

Comments
 (0)