Current section
Files
Jump to
Current section
Files
src/alara_node_sup.erl
-module(alara_node_sup).
-behaviour(supervisor).
%% API
-export([start_link/1, start_node/0, get_nodes/0, generate_random_bools/1, generate_random_int/1]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%%===================================================================
%%% API functions
%%%===================================================================
start_link(NumNodes) ->
supervisor:start_link({local, ?SERVER}, ?MODULE, NumNodes).
%% Start a new node instance
start_node() ->
supervisor:start_child(?SERVER, []).
get_nodes() ->
[Pid || {_Id, Pid, _Type, _Modules} <- supervisor:which_children(?SERVER)].
% Generate N random booleans from all nodes (distributed)
generate_random_bools(N) when is_integer(N), N > 0 ->
Nodes = get_nodes(),
case length(Nodes) of
0 -> {error, no_nodes};
NumNodes ->
BitsPerNode = N div NumNodes,
Remainder = N rem NumNodes,
%% Collect bits from each node
BaseBits = lists:flatmap(
fun(Node) ->
[alara_node:get_random(Node) || _ <- lists:seq(1, BitsPerNode)]
end,
Nodes
),
%% Get remaining bits from first node if needed
case Remainder of
0 -> BaseBits;
R -> BaseBits ++ [alara_node:get_random(hd(Nodes)) || _ <- lists:seq(1, R)]
end
end.
%% Generate a random integer using NBits
generate_random_int(NBits) when is_integer(NBits), NBits > 0 ->
case generate_random_bools(NBits) of
{error, Reason} -> {error, Reason};
Bits -> bits_to_integer(Bits)
end.
%%%===================================================================
%%% Supervisor callbacks
%%%===================================================================
init(NumNodes) ->
SupFlags = #{
strategy => one_for_one,
intensity => 10,
period => 5
},
ChildSpecs = [
#{
id => {alara_node, I},
start => {alara_node, start_link, []},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [alara_node]
}
|| I <- lists:seq(1, NumNodes)
],
{ok, {SupFlags, ChildSpecs}}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
bits_to_integer(Bits) ->
lists:foldl(
fun(Bit, Acc) ->
BitValue = case Bit of
true -> 1;
false -> 0;
1 -> 1;
0 -> 0
end,
(Acc bsl 1) bor BitValue
end,
0,
Bits
).