2323
2424-export ([start /0 ]).
2525
26- -export ([setup_benchmark /1 , run_benchmark /1 , await_completion /1 , main /1 , md5 /1 , get_test_dir /0 ]).
26+ -export ([setup_benchmark /2 , run_benchmark /0 , await_completion /1 , main /1 , md5 /1 , get_test_dir /0 ]).
27+ -export ([master_node /0 , node_count /0 , is_master /0 , is_worker /0 , is_clustered /0 ]).
2728-include (" basho_bench.hrl" ).
2829
2930
31+ -define (AWAIT_TIMEOUT , 10000 ).
32+
33+
3034start () ->
3135 application :ensure_all_started (basho_bench ).
3236
3337% % ====================================================================
3438% % API
3539% % ====================================================================
3640
37- setup_benchmark (Opts ) ->
41+ setup_benchmark (Opts , Configs ) ->
3842 BenchName = bench_name (Opts ),
3943 TestDir = test_dir (Opts , BenchName ),
4044 application :set_env (basho_bench , test_dir , TestDir ),
@@ -66,10 +70,7 @@ setup_benchmark(Opts) ->
6670 true -> setup_distributed_work ();
6771 false -> ok
6872 end ,
69- ok .
7073
71-
72- run_benchmark (Configs ) ->
7374 TestDir = get_test_dir (),
7475 % % Init code path
7576 add_code_paths (basho_bench_config :get (code_paths , [])),
@@ -93,11 +94,35 @@ run_benchmark(Configs) ->
9394
9495 log_dimensions (),
9596
97+ ok .
98+
99+
100+ run_benchmark () ->
96101 basho_bench_sup :start_child (),
97- ok = basho_bench_stats :run (),
98- ok = basho_bench_measurement :run (),
99- ok = basho_bench_duration :run (),
100- ok = basho_bench_worker :run (basho_bench_worker_sup :workers ()),
102+ case {master_node (), node_count ()} of
103+ % % No master
104+ {undefined , _ } ->
105+ bootstrap_bb (),
106+ ok = run_benchmarks (basho_bench_worker_sup :workers ());
107+ % % Only one node, equivalent to no master
108+ {_ , 1 } ->
109+ bootstrap_bb (),
110+ ok = run_benchmarks (basho_bench_worker_sup :workers ());
111+ % % Master and multiple workers
112+ {MasterNode , NodeCount } when NodeCount > 1 ->
113+ case MasterNode =:= node () of
114+ true ->
115+ await_nodes (NodeCount ),
116+ bootstrap_bb (),
117+ ok = run_benchmarks ();
118+ false ->
119+ ? INFO (" Worker node[~p ] connecting to master node: ~p~n " , [node (), MasterNode ]),
120+ pong = net_adm :ping (MasterNode ),
121+ true = length (nodes ()) > 0 ,
122+ % % Let master node decide when to run benchmarks
123+ ok = basho_bench_duration :run ()
124+ end
125+ end ,
101126 application :set_env (basho_bench_app , is_running , true ).
102127
103128
@@ -117,8 +142,8 @@ main(Args) ->
117142 ok = maybe_net_node (Opts ),
118143 ok = maybe_join (Opts ),
119144 {ok , _ } = start (),
120- setup_benchmark (Opts ),
121- run_benchmark (Configs ),
145+ setup_benchmark (Opts , Configs ),
146+ run_benchmark (),
122147 await_completion (infinity ).
123148
124149
@@ -346,3 +371,71 @@ get_test_dir() ->
346371 undefined -> error (unset_test_dir );
347372 {ok , TestDir } -> TestDir
348373 end .
374+
375+ master_node () ->
376+ Default = case init :get_argument (master_node ) of
377+ {ok , [[Node ]]} -> list_to_atom (Node );
378+ _ -> node ()
379+ end ,
380+ case catch basho_bench_config :get (master_node , undefined ) of
381+ {'EXIT' , {noproc , _ }} ->
382+ Default ;
383+ undefined ->
384+ Default ;
385+ Res ->
386+ Res
387+ end .
388+
389+ node_count () ->
390+ Default = case init :get_argument (node_count ) of
391+ {ok , [[NodeCount ]]} -> list_to_integer (NodeCount );
392+ _ -> 1
393+ end ,
394+ case catch basho_bench_config :get (node_count , undefined ) of
395+ {'EXIT' , {noproc , _ }} ->
396+ Default ;
397+ undefined ->
398+ Default ;
399+ Res ->
400+ Res
401+ end .
402+
403+ is_master () ->
404+ master_node () =:= node ().
405+
406+ is_worker () ->
407+ not is_master () and is_clustered ().
408+
409+ is_clustered () ->
410+ node_count () > 1 .
411+
412+ await_nodes (NodeCount ) ->
413+ await_nodes (NodeCount , 100 ).
414+
415+ await_nodes (NodeCount , SleepMS ) ->
416+ await_nodes (NodeCount , SleepMS , ? AWAIT_TIMEOUT ).
417+
418+ await_nodes (_ , _ , Timeout ) when Timeout < 0 ->
419+ throw ({error , await_node_timeout });
420+ await_nodes (NodeCount , SleepMS , Timeout ) ->
421+ case NodeCount =:= length (nodes ()) + 1 of
422+ true ->
423+ ok ;
424+ false ->
425+ ? INFO (" Waiting on ~p nodes to connect~n " , [NodeCount - length (nodes ()) - 1 ]),
426+ timer :sleep (SleepMS ),
427+ await_nodes (NodeCount , SleepMS * 2 , Timeout - SleepMS )
428+ end .
429+
430+ bootstrap_bb () ->
431+ ok = basho_bench_stats :run (),
432+ ok = basho_bench_measurement :run (),
433+ ok = basho_bench_duration :run ().
434+
435+ run_benchmarks () ->
436+ Pids0 = [basho_bench_worker_sup :remote_workers (Node ) || Node <- nodes ()],
437+ Pids = lists :flatten ([basho_bench_worker_sup :workers () | Pids0 ]),
438+ run_benchmarks (Pids ).
439+
440+ run_benchmarks (Pids ) ->
441+ ok = basho_bench_worker :run (Pids ).
0 commit comments