108 lines
3.7 KiB
Erlang
108 lines
3.7 KiB
Erlang
-module(benchmarker).
|
|
-export([init/0, startServiceTime/2, startOpenLoop/3,
|
|
startClosedLoop/4, stop/0, inactive/0]).
|
|
|
|
%% @spec init() -> void()
|
|
%% @doc Initialize the benchmark.
|
|
%% This must be done only the first time.
|
|
init() ->
|
|
application:start(spsBenchmark),
|
|
inets:start(),
|
|
ssl:start(),
|
|
statistician:init(),
|
|
BenchmarkerPid = spawn(?MODULE, inactive, []),
|
|
register(benchmarker, BenchmarkerPid).
|
|
|
|
%% @spec startServiceTime(Duration::integer(), Warmup::integer()) -> void()
|
|
%% @doc Start the benchmark to calculate the service time.
|
|
startServiceTime(Duration, Warmup) ->
|
|
benchmarker !
|
|
{start_benchmark, service_time, Duration * 1000, Warmup * 1000}.
|
|
|
|
%% @spec startOpenLoop(Rate::float(), Duration::integer(),
|
|
%% Warmup::integer()) -> void
|
|
%% @doc Start the benchmark in an open loop.
|
|
startOpenLoop(Rate, Duration, Warmup) ->
|
|
benchmarker !
|
|
{start_benchmark, open_loop, Rate, Duration * 1000, Warmup * 1000}.
|
|
|
|
%% @spec startClosedLoop(Rate::float(), NumWorkers::integer(),
|
|
%% Duration::integer(), Warmup::integer()) -> void()
|
|
%% @doc Start the benchmark in a closed loop.
|
|
startClosedLoop(Rate, NumWorkers, Duration, Warmup) ->
|
|
benchmarker !
|
|
{start_benchmark, closed_loop, Rate, NumWorkers,
|
|
Duration * 1000, Warmup * 1000}.
|
|
|
|
%% @spec stop() -> void
|
|
%% @doc Stop the benchmark.
|
|
stop() ->
|
|
benchmarker ! {stop_benchmark}.
|
|
|
|
%% @spec inactive() -> void()
|
|
%% @doc The benchmark is inactive, wait for a message to start.
|
|
inactive() ->
|
|
receive
|
|
{start_benchmark, service_time, Duration, Warmup} ->
|
|
RequesterPid = requester:init(),
|
|
erlang:monitor(process, RequesterPid),
|
|
requester:startServiceTime(RequesterPid),
|
|
io:format("Starting service time benchmark~n"),
|
|
warmup(RequesterPid, Duration, Warmup);
|
|
{start_benchmark, open_loop, Rate, Duration, Warmup} ->
|
|
RequesterPid = requester:init(),
|
|
erlang:monitor(process, RequesterPid),
|
|
requester:startOpenLoop(RequesterPid, Rate),
|
|
io:format("Starting open loop benchmark~n"),
|
|
warmup(RequesterPid, Duration, Warmup);
|
|
{start_benchmark, closed_loop, Rate, NumWorkers, Duration, Warmup} ->
|
|
RequesterPid = requester:init(),
|
|
erlang:monitor(process, RequesterPid),
|
|
requester:startClosedLoop(RequesterPid, Rate, NumWorkers),
|
|
io:format("Starting closed loop benchmark~n"),
|
|
warmup(RequesterPid, Duration, Warmup)
|
|
end.
|
|
|
|
%% @spec warmup(RequesterPid::pid(), Duration::integer(),
|
|
%% Warmup::integer()) -> void()
|
|
%% @doc Start the warmup and start recording statistics at the end of it.
|
|
warmup(RequesterPid, Duration, Warmup) ->
|
|
receive
|
|
{stop_benchmark} ->
|
|
RequesterPid ! {stop}
|
|
after Warmup ->
|
|
statistician:startRecording(),
|
|
active(Duration, RequesterPid)
|
|
end.
|
|
|
|
%% @spec active(Duration::integer(), RequesterPid::pid()) -> void()
|
|
%% @doc The benchmark is active, print the statistics
|
|
%% periodically and when the benchmark ends.
|
|
active(Duration, RequesterPid) ->
|
|
receive
|
|
{'DOWN', _MonitorReference, process, _Pid, _Reason} ->
|
|
io:format("Requester ended before benchmarker finished~n"),
|
|
statistician:printStatistics(),
|
|
statistician:stopRecording(),
|
|
inactive();
|
|
{stop_benchmark} ->
|
|
RequesterPid ! {stop}
|
|
after Duration ->
|
|
requester:printActiveWorkers(RequesterPid),
|
|
requester:stop(RequesterPid),
|
|
statistician:printStatistics(),
|
|
statistician:stopRecording(),
|
|
deactivate()
|
|
end.
|
|
|
|
%% @spec deactivate() -> void()
|
|
%% @doc The benchmark waits the requester to finish.
|
|
%% This make sure that there won't be any active requests
|
|
%% before starting a new benchmark.
|
|
deactivate() ->
|
|
receive
|
|
{'DOWN', _MonitorReference, process, _Pid, _Reason} ->
|
|
% io:format("Benchmarker is ready~n"),
|
|
inactive()
|
|
end.
|