Configure FLUs and chains with "rc.d" style configuration #56

Merged
slfritchie merged 43 commits from slf/flu-config-rcd-style into master 2015-12-18 06:46:05 +00:00
4 changed files with 73 additions and 6 deletions
Showing only changes of commit 3c880dc437 - Show all commits

View file

@ -75,4 +75,11 @@
%% create a consistent projection ranking score. %% create a consistent projection ranking score.
-define(MAX_CHAIN_LENGTH, 64). -define(MAX_CHAIN_LENGTH, 64).
-record(chain_def_v1, {
name :: atom(),
mode :: pv1_consistency_mode(),
upi :: [pv1_server()],
witnesses :: [pv1_server()]
}).
-endif. % !MACHI_PROJECTION_HRL -endif. % !MACHI_PROJECTION_HRL

View file

@ -22,6 +22,8 @@
-behaviour(gen_server). -behaviour(gen_server).
-include("machi_projection.hrl").
%% API %% API
-export([start_link/0]). -export([start_link/0]).
@ -52,6 +54,8 @@ handle_info(finish_init, State) ->
FLU_Epochs = get_latest_public_epochs(FLUs), FLU_Epochs = get_latest_public_epochs(FLUs),
FLUs_at_zero = [FLU || {FLU, 0} <- FLU_Epochs], FLUs_at_zero = [FLU || {FLU, 0} <- FLU_Epochs],
lager:info("FLUs at epoch 0: ~p\n", [FLUs_at_zero]), lager:info("FLUs at epoch 0: ~p\n", [FLUs_at_zero]),
ChainDefs = get_initial_chains(),
perhaps_bootstrap_chains(ChainDefs, FLUs),
{noreply, State}; {noreply, State};
handle_info(_Info, State) -> handle_info(_Info, State) ->
{noreply, State}. {noreply, State}.
@ -74,3 +78,60 @@ get_latest_public_epochs(FLUs) ->
PS, public), PS, public),
{FLU, Epoch} {FLU, Epoch}
end || FLU <- FLUs]. end || FLU <- FLUs].
get_initial_chains() ->
DoesNotExist = "/tmp/does/not/exist",
ConfigDir = case application:get_env(machi, chain_config_dir, DoesNotExist) of
DoesNotExist ->
DoesNotExist;
Dir ->
ok = filelib:ensure_dir(Dir ++ "/unused"),
Dir
end,
sanitize_chain_def_records(machi_flu_sup:load_rc_d_files_from_dir(ConfigDir)).
sanitize_chain_def_records(Ps) ->
{Sane, _} = lists:foldl(fun sanitize_chain_def_rec/2, {[], dict:new()}, Ps),
Sane.
sanitize_chain_def_rec(Whole, {Acc, D}) ->
try
#chain_def_v1{name=Name,
mode=Mode,
upi=UPI,
witnesses=Witnesses} = Whole,
true = is_atom(Name),
NameK = {name, Name},
error = dict:find(NameK, D),
true = (Mode == ap_mode orelse Mode == cp_mode),
IsPSrvr = fun(X) when is_record(X, p_srvr) -> true;
(_) -> false
end,
true = lists:all(IsPSrvr, UPI),
true = lists:all(IsPSrvr, Witnesses),
%% All is sane enough.
D2 = dict:store(NameK, Name, D),
{[Whole|Acc], D2}
catch _:_ ->
_ = lager:log(error, self(),
"~s: Bad chain_def record, skipping: ~P\n",
[?MODULE, Whole, 15]),
{Acc, D}
end.
perhaps_bootstrap_chains([], _FLUs) ->
ok;
perhaps_bootstrap_chains([CD|ChainDefs], FLUs) ->
#chain_def_v1{upi=UPI, witnesses=Witnesses} = CD,
AllNames = [Name || #p_srvr{name=Name} <- UPI ++ Witnesses],
case ordsets:intersection(ordsets:from_list(AllNames),
ordsets:from_list(FLUs)) of
[] ->
io:format(user, "TODO: no local flus in ~P\n", [CD, 10]),
ok;
[FLU1|_] ->
io:format(user, "TODO: config ~p as bootstrap member of ~p\n", [FLU1, CD]),
yoyo
end,
perhaps_bootstrap_chains(ChainDefs, FLUs).

View file

@ -44,7 +44,7 @@
-endif. %TEST -endif. %TEST
%% API %% API
-export([start_link/0]). -export([start_link/0, load_rc_d_files_from_dir/1]).
%% Supervisor callbacks %% Supervisor callbacks
-export([init/1]). -export([init/1]).

View file

@ -62,9 +62,8 @@ init([]) ->
ServerSup = ServerSup =
{machi_flu_sup, {machi_flu_sup, start_link, []}, {machi_flu_sup, {machi_flu_sup, start_link, []},
Restart, Shutdown, Type, []}, Restart, Shutdown, Type, []},
ChainBootstrap =
{machi_chain_bootstrap, {machi_chain_bootstrap, start_link, []},
Restart, Shutdown, worker, []},
{ok, {SupFlags, [ServerSup]}}. {ok, {SupFlags, [ServerSup, ChainBootstrap]}}.
%% AChild = {'AName', {'AModule', start_link, []},
%% Restart, Shutdown, Type, ['AModule']},
%% {ok, {SupFlags, [AChild]}}.