Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save potatosalad/aa540429547a81e98b603956111b7ad2 to your computer and use it in GitHub Desktop.

Select an option

Save potatosalad/aa540429547a81e98b603956111b7ad2 to your computer and use it in GitHub Desktop.
20251003-zeyu-socket-accept-regression
-module(zeyu_socket_accept_regression_client).
-export([client/1]).
client(IPv6Address) ->
Ref = atomics:new(1, []),
socket:use_registry(false),
[spawn(fun() -> client(Ref, IPv6Address) end) || _ <- lists:seq(1, 200)],
spawn(fun() -> report(Ref, 0, erlang:system_time(millisecond)) end).
client(Ref, Addr) ->
{ok, Socket} = socket:open(inet6, stream, tcp, #{use_registry => false}),
Result = socket:connect(Socket, #{family => inet6, port => 5223, addr => Addr}),
Result =:= ok andalso atomics:add(Ref, 1, 1),
socket:close(Socket),
client(Ref).
report(Ref, LastCount, LastTime) ->
timer:sleep(1000),
Now = erlang:system_time(millisecond),
Count = atomics:get(Ref, 1),
io:format("c:~.3fk/s~n", [(Count - LastCount) / (Now - LastTime)]),
report(Ref, Count, Now).
Ref = atomics:new(1, []),
[spawn_link(fun() -> client(Ref) end) || _ <- lists:seq(1, 5000)],
spawn_link(fun() -> report(Ref, 0, erlang:system_time(millisecond)) end).
-module(zeyu_socket_accept_regression_server).
-export([server/0]).
server() ->
Ref = atomics:new(2, []),
socket:use_registry(false),
{ok, ListenSocket} = socket:open(inet6, stream, tcp, #{use_registry => false}),
ok = socket:setopt(ListenSocket, {socket, reuseaddr}, true),
ok = socket:bind(ListenSocket, #{family => inet6, port => 5223, addr => any}),
{ok, #{port := _AssignedPort}} = socket:sockname(ListenSocket),
ok = socket:listen(ListenSocket, 5223),
[spawn_link(fun() -> acceptor(Ref, ListenSocket) end) || _ <- lists:seq(1, 16)],
spawn_link(fun() -> report(Ref, 0, 0, erlang:system_time(millisecond)) end).
acceptor(Ref, ListenSocket) ->
case socket:accept(ListenSocket, 10000) of
{ok, Socket} ->
atomics:add(Ref, 1, 1),
socket:close(Socket),
acceptor(Ref, ListenSocket);
_ ->
acceptor(Ref, ListenSocket)
end.
report(Ref, LastSpawn, LastClose, LastTime) ->
timer:sleep(1000),
Now = erlang:system_time(millisecond),
Spawn = atomics:get(Ref, 1),
Close = atomics:get(Ref, 2),
io:format("s:~.3fk/s,~.3fk/s~n", [(Spawn - LastSpawn) / (Now - LastTime), (Close - LastClose) / (Now - LastTime)]),
report(Ref, Spawn, Close, Now).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment