Last active
August 27, 2022 22:59
-
-
Save RoadRunnr/311a7679fff6fbdf367c455b960f1ba8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env escript | |
%% -*- erlang -*- | |
%%! +sbtu +A1 | |
-mode(compile). | |
-export([init_server/1]). | |
-define(UNIT, nanosecond). | |
%%-define(UNIT, millisecond). | |
main(_) -> | |
{ok, Server, SockAddr} = start_server(), | |
io:format("Server Pid ~p~nServer Addr ~p~n", [Server, SockAddr]), | |
{ok, Socket} = gen_udp:open(0, [binary, inet, {active, false}]), | |
Load = [proc_lib:spawn_link(fun busy_loop/0) || | |
_ <- lists:seq(0, erlang:system_info(schedulers) * 2)], | |
Stats = ping(Server, Socket, SockAddr, 1000, []), | |
io:format(" round trip Clnt/Srvr Srvr/Clnt ProcPing~n"), | |
[io:format("~8w: ~8w ns, ~8w ns, ~8w ns, ~8w ns~n", | |
[Cnt, RecvTS - SendTS, RecvTS - SrvTS, | |
SrvTS - SendTS, PingTS - RecvTS]) || | |
{Cnt, RecvTS, SendTS, SrvTS, PingTS} <- Stats], | |
[P ! stop || P <- Load], | |
Server ! stop. | |
ping(Server) -> | |
erlang:send(Server, {ping, self()}, [noconnect]), | |
receive | |
pong -> ok | |
after 2000 -> | |
io:format("ping timeout~n") | |
end. | |
ping(_Server, _Socket, _Dest, 0, Stats) -> | |
lists:reverse(Stats); | |
ping(Server, Socket, #{addr := Addr, port := Port} = Dest, Cnt, Stats0) -> | |
%%timer:sleep(rand:uniform(1000)), | |
%%timer:sleep(2000), | |
SendTS = erlang:monotonic_time(?UNIT), | |
Fill = binary:list_to_bin(lists:duplicate(1000, 0)), | |
Data = term_to_binary({Cnt, SendTS, Fill}), | |
ping(Server), | |
ok = gen_udp:send(Socket, Addr, Port, Data), | |
ping(Server), | |
{ok, {_, _, Answer}} = gen_udp:recv(Socket, 0, infinity), | |
erlang:send(Server, hi, [noconnect]), | |
RecvTS = erlang:monotonic_time(?UNIT), | |
Mref = erlang:monitor(process, Server), | |
ping(Server), | |
erlang:demonitor(Mref, [flush]), | |
PingTS = erlang:monotonic_time(?UNIT), | |
{Cnt, _, SrvTS, _} = binary_to_term(Answer), | |
Stats = [{Cnt, RecvTS, SendTS, SrvTS, PingTS}|Stats0], | |
ping(Server, Socket, Dest, Cnt - 1, Stats). | |
busy_loop() -> | |
receive | |
stop -> | |
ok | |
after | |
1 -> | |
busy_loop() | |
end. | |
start_server() -> | |
{ok, _, _} = proc_lib:start_link(?MODULE, init_server, [self()]). | |
init_server(Parent) -> | |
{ok, Socket} = socket:open(inet, dgram, udp), | |
{ok, _} = socket:bind(Socket, loopback), | |
{ok, SockAddr} = socket:sockname(Socket), | |
proc_lib:init_ack(Parent, {ok, self(), SockAddr}), | |
server_loop(Socket). | |
server_loop(Socket) -> | |
server_loop(Socket, 10). | |
server_loop(Socket, 0) -> | |
self() ! {'$socket', Socket, select, undefined}, | |
select_loop(Socket); | |
server_loop(Socket, BusyCnt) -> | |
case socket:recvfrom(Socket, 0, [], nowait) of | |
{ok, {Source, Data}} -> | |
SrvTS = erlang:monotonic_time(?UNIT), | |
{Cnt, SendTS, Fill} = binary_to_term(Data), | |
Answer = term_to_binary({Cnt, SendTS, SrvTS, Fill}), | |
socket:sendto(Socket, Answer, Source, [], nowait), | |
server_loop(Socket, BusyCnt - 1); | |
{select, _} -> | |
select_loop(Socket); | |
{error, Reason} -> | |
exit(Reason) | |
end. | |
select_loop(Socket) -> | |
receive | |
hi -> | |
select_loop(Socket); | |
{ping, Pid} -> | |
Pid ! pong, | |
select_loop(Socket); | |
stop -> | |
ok; | |
{'$socket', Socket, abort, _} -> | |
io:format("Socket Error"), | |
ok; | |
{'$socket', Socket, select, _} -> | |
server_loop(Socket) | |
end. |
No. But why would it matter if it does or does not work with two VMs? Using socket.erl should not break Erlang message passing in either case, yet it clearly does.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It looks like you have both proc's running in the same VM.
Have you tried it in different VMs?
/BMK