-module(fuzed_node_supervisor). -behaviour(supervisor). -export([start/0, start_shell/0, start_link/1, init/1]). -include("../include/fuzed.hrl"). % Supervisor Functions start() -> spawn(fun() -> supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []) end). start_shell() -> {ok, Pid} = supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []), unlink(Pid). start_link(Args) -> supervisor:start_link({local, ?MODULE}, ?MODULE, Args). init([]) -> Master = application:get_env(master), case Master of {ok, MasterNode} -> ping_master(MasterNode); undefined -> MasterNode = node() end, {ok, NumNodes} = application:get_env(num_nodes), {ok, Spec} = application:get_env(spec), init_helper(MasterNode, NumNodes, Spec). % Helper functions ping_master(Node) -> case net_adm:ping(Node) of pong -> timer:sleep(?SLEEP_CYCLE), ok; pang -> error_logger:info_msg("Master node ~p not available. Retrying in 5 seconds.~n", [Node]), timer:sleep(?SLEEP_CYCLE), ping_master(Node) end. init_helper(Master, NumNodes, Spec) when integer(NumNodes) -> error_logger:info_msg("Starting with ~p set(s) of nodes.~n", [NumNodes]), start_rm(Master, explode_spec(Spec, NumNodes)). explode_spec(Specs, N) -> SBins = [list_to_binary(X) || X <- Specs], lists:sort([binary_to_list(X) || X <- lists:flatten(lists:duplicate(N, SBins))]). start_rm(Master, NodeSpec) -> error_logger:info_msg("Starting with spec: ~p~n", [NodeSpec]), Maker = fun(N) -> node_api:heat(N, ?HEAT_DURATION) end, Killer = fun(X) -> X end, {ok, {{one_for_one, 10, 600}, [{resource_manager, {resource_manager, start_link, [Master, NodeSpec, Maker, Killer, ?GLOBAL_TIMEOUT]}, permanent, 10000, worker, [resource_manager]}, {master_beater, {master_beater, start_link, [Master, ?GLOBAL_TIMEOUT, ?SLEEP_CYCLE]}, permanent, 10000, worker, [master_beater]} ]}}.