Configure FLUs and chains with "rc.d" style configuration #56
9 changed files with 100 additions and 60 deletions
|
@ -22,10 +22,11 @@
|
||||||
-define(MACHI_PROJECTION_HRL, true).
|
-define(MACHI_PROJECTION_HRL, true).
|
||||||
|
|
||||||
-type pv1_consistency_mode() :: 'ap_mode' | 'cp_mode'.
|
-type pv1_consistency_mode() :: 'ap_mode' | 'cp_mode'.
|
||||||
|
-type pv1_chain_name():: atom().
|
||||||
-type pv1_csum() :: binary().
|
-type pv1_csum() :: binary().
|
||||||
-type pv1_epoch() :: {pv1_epoch_n(), pv1_csum()}.
|
-type pv1_epoch() :: {pv1_epoch_n(), pv1_csum()}.
|
||||||
-type pv1_epoch_n() :: non_neg_integer().
|
-type pv1_epoch_n() :: non_neg_integer().
|
||||||
-type pv1_server() :: atom() | binary().
|
-type pv1_server() :: atom().
|
||||||
-type pv1_timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
|
-type pv1_timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
|
||||||
|
|
||||||
-record(p_srvr, {
|
-record(p_srvr, {
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
epoch_number :: pv1_epoch_n() | ?SPAM_PROJ_EPOCH,
|
epoch_number :: pv1_epoch_n() | ?SPAM_PROJ_EPOCH,
|
||||||
epoch_csum :: pv1_csum(),
|
epoch_csum :: pv1_csum(),
|
||||||
author_server :: pv1_server(),
|
author_server :: pv1_server(),
|
||||||
|
chain_name = ch_not_def_yet :: pv1_chain_name(),
|
||||||
all_members :: [pv1_server()],
|
all_members :: [pv1_server()],
|
||||||
witnesses = [] :: [pv1_server()],
|
witnesses = [] :: [pv1_server()],
|
||||||
creation_time :: pv1_timestamp(),
|
creation_time :: pv1_timestamp(),
|
||||||
|
|
|
@ -330,18 +330,17 @@ message Mpb_ProjectionV1 {
|
||||||
required uint32 epoch_number = 1;
|
required uint32 epoch_number = 1;
|
||||||
required bytes epoch_csum = 2;
|
required bytes epoch_csum = 2;
|
||||||
required string author_server = 3;
|
required string author_server = 3;
|
||||||
repeated string all_members = 4;
|
required string chain_name = 4;
|
||||||
repeated string witnesses = 5;
|
repeated string all_members = 5;
|
||||||
required Mpb_Now creation_time = 6;
|
repeated string witnesses = 6;
|
||||||
required Mpb_Mode mode = 7;
|
required Mpb_Now creation_time = 7;
|
||||||
repeated string upi = 8;
|
required Mpb_Mode mode = 8;
|
||||||
repeated string repairing = 9;
|
repeated string upi = 9;
|
||||||
repeated string down = 10;
|
repeated string repairing = 10;
|
||||||
optional bytes opaque_flap = 11;
|
repeated string down = 11;
|
||||||
optional bytes opaque_inner = 12;
|
required bytes opaque_dbg = 12;
|
||||||
required bytes opaque_dbg = 13;
|
required bytes opaque_dbg2 = 13;
|
||||||
required bytes opaque_dbg2 = 14;
|
repeated Mpb_MembersDictEntry members_dict = 14;
|
||||||
repeated Mpb_MembersDictEntry members_dict = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
|
@ -131,7 +131,10 @@ perhaps_bootstrap_chains([CD|ChainDefs], FLUs) ->
|
||||||
io:format(user, "TODO: no local flus in ~P\n", [CD, 10]),
|
io:format(user, "TODO: no local flus in ~P\n", [CD, 10]),
|
||||||
ok;
|
ok;
|
||||||
[FLU1|_] ->
|
[FLU1|_] ->
|
||||||
io:format(user, "TODO: config ~p as bootstrap member of ~p\n", [FLU1, CD]),
|
bootstrap_chain(CD, FLU1)
|
||||||
yoyo
|
|
||||||
end,
|
end,
|
||||||
perhaps_bootstrap_chains(ChainDefs, FLUs).
|
perhaps_bootstrap_chains(ChainDefs, FLUs).
|
||||||
|
|
||||||
|
bootstrap_chain(CD, FLU) ->
|
||||||
|
io:format(user, "TODO: config ~p as bootstrap member of ~p\n", [FLU, CD]),
|
||||||
|
todo.
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start_link/2, start_link/3, stop/1, ping/1,
|
-export([start_link/2, start_link/3, stop/1, ping/1,
|
||||||
set_chain_members/2, set_chain_members/3, set_active/2,
|
set_chain_members/2, set_chain_members/6, set_active/2,
|
||||||
trigger_react_to_env/1]).
|
trigger_react_to_env/1]).
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
terminate/2, format_status/2, code_change/3]).
|
terminate/2, format_status/2, code_change/3]).
|
||||||
|
@ -168,13 +168,22 @@ ping(Pid) ->
|
||||||
%% with lowest rank, i.e. name z* first, name a* last.
|
%% with lowest rank, i.e. name z* first, name a* last.
|
||||||
|
|
||||||
set_chain_members(Pid, MembersDict) ->
|
set_chain_members(Pid, MembersDict) ->
|
||||||
set_chain_members(Pid, MembersDict, []).
|
set_chain_members(Pid, ch0_name, 0, ap_mode, MembersDict, []).
|
||||||
|
|
||||||
set_chain_members(Pid, MembersDict, Witness_list) ->
|
set_chain_members(Pid, ChainName, OldEpoch, CMode, MembersDict, Witness_list)
|
||||||
case lists:all(fun(Witness) -> orddict:is_key(Witness, MembersDict) end,
|
when is_atom(ChainName) andalso
|
||||||
|
is_integer(OldEpoch) andalso OldEpoch >= 0 andalso
|
||||||
|
(CMode == ap_mode orelse CMode == cp_mode) andalso
|
||||||
|
is_list(MembersDict) andalso
|
||||||
|
is_list(Witness_list) ->
|
||||||
|
case lists:all(fun({X, #p_srvr{name=X}}) -> true;
|
||||||
|
(_) -> false
|
||||||
|
end, MembersDict)
|
||||||
|
andalso
|
||||||
|
lists:all(fun(Witness) -> orddict:is_key(Witness, MembersDict) end,
|
||||||
Witness_list) of
|
Witness_list) of
|
||||||
true ->
|
true ->
|
||||||
Cmd = {set_chain_members, MembersDict, Witness_list},
|
Cmd = {set_chain_members, ChainName, OldEpoch, CMode, MembersDict, Witness_list},
|
||||||
gen_server:call(Pid, Cmd, infinity);
|
gen_server:call(Pid, Cmd, infinity);
|
||||||
false ->
|
false ->
|
||||||
{error, bad_arg}
|
{error, bad_arg}
|
||||||
|
@ -291,7 +300,8 @@ init({MyName, InitMembersDict, MgrOpts}) ->
|
||||||
|
|
||||||
handle_call({ping}, _From, S) ->
|
handle_call({ping}, _From, S) ->
|
||||||
{reply, pong, S};
|
{reply, pong, S};
|
||||||
handle_call({set_chain_members, MembersDict, Witness_list}, _From,
|
handle_call({set_chain_members, ChainName, OldEpoch, CMode,
|
||||||
|
MembersDict, Witness_list}, _From,
|
||||||
#ch_mgr{name=MyName,
|
#ch_mgr{name=MyName,
|
||||||
proj=#projection_v1{all_members=OldAll_list,
|
proj=#projection_v1{all_members=OldAll_list,
|
||||||
epoch_number=OldEpoch,
|
epoch_number=OldEpoch,
|
||||||
|
@ -310,10 +320,10 @@ handle_call({set_chain_members, MembersDict, Witness_list}, _From,
|
||||||
{NUPI, All_list -- NUPI}
|
{NUPI, All_list -- NUPI}
|
||||||
end,
|
end,
|
||||||
NewEpoch = OldEpoch + ?SET_CHAIN_MEMBERS_EPOCH_SKIP,
|
NewEpoch = OldEpoch + ?SET_CHAIN_MEMBERS_EPOCH_SKIP,
|
||||||
CMode = calc_consistency_mode(Witness_list),
|
|
||||||
ok = set_consistency_mode(machi_flu_psup:make_proj_supname(MyName), CMode),
|
ok = set_consistency_mode(machi_flu_psup:make_proj_supname(MyName), CMode),
|
||||||
NewProj = machi_projection:update_checksum(
|
NewProj = machi_projection:update_checksum(
|
||||||
OldProj#projection_v1{author_server=MyName,
|
OldProj#projection_v1{author_server=MyName,
|
||||||
|
chain_name=ChainName,
|
||||||
creation_time=now(),
|
creation_time=now(),
|
||||||
mode=CMode,
|
mode=CMode,
|
||||||
epoch_number=NewEpoch,
|
epoch_number=NewEpoch,
|
||||||
|
@ -601,6 +611,8 @@ rank_and_sort_projections_with_extra(All_queried_list, FLUsRs, ProjectionType,
|
||||||
Witness_list = CurrentProj#projection_v1.witnesses,
|
Witness_list = CurrentProj#projection_v1.witnesses,
|
||||||
NoneProj = make_none_projection(0, MyName, [], Witness_list,
|
NoneProj = make_none_projection(0, MyName, [], Witness_list,
|
||||||
orddict:new()),
|
orddict:new()),
|
||||||
|
ChainName = CurrentProj#projection_v1.chain_name,
|
||||||
|
NoneProj2 = NoneProj#projection_v1{chain_name=ChainName},
|
||||||
Extra2 = [{all_members_replied, true},
|
Extra2 = [{all_members_replied, true},
|
||||||
{all_queried_list, All_queried_list},
|
{all_queried_list, All_queried_list},
|
||||||
{flus_rs, FLUsRs},
|
{flus_rs, FLUsRs},
|
||||||
|
@ -723,13 +735,14 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
runenv=RunEnv1,
|
runenv=RunEnv1,
|
||||||
repair_final_status=RepairFS}=S) ->
|
repair_final_status=RepairFS}=S) ->
|
||||||
#projection_v1{epoch_number=OldEpochNum,
|
#projection_v1{epoch_number=OldEpochNum,
|
||||||
|
chain_name=ChainName,
|
||||||
members_dict=MembersDict,
|
members_dict=MembersDict,
|
||||||
witnesses=OldWitness_list,
|
witnesses=OldWitness_list,
|
||||||
upi=OldUPI_list,
|
upi=OldUPI_list,
|
||||||
repairing=OldRepairing_list
|
repairing=OldRepairing_list
|
||||||
} = LastProj,
|
} = LastProj,
|
||||||
LastUp = lists:usort(OldUPI_list ++ OldRepairing_list),
|
LastUp = lists:usort(OldUPI_list ++ OldRepairing_list),
|
||||||
AllMembers = (S#ch_mgr.proj)#projection_v1.all_members,
|
AllMembers = CurrentProj#projection_v1.all_members,
|
||||||
{Up0, Partitions, RunEnv2} = calc_up_nodes(MyName,
|
{Up0, Partitions, RunEnv2} = calc_up_nodes(MyName,
|
||||||
AllMembers, RunEnv1),
|
AllMembers, RunEnv1),
|
||||||
Up = Up0 -- AllHosed,
|
Up = Up0 -- AllHosed,
|
||||||
|
@ -821,10 +834,11 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
end,
|
end,
|
||||||
?REACT({calc,?LINE,[{new_upi, NewUPI},{new_rep, NewRepairing}]}),
|
?REACT({calc,?LINE,[{new_upi, NewUPI},{new_rep, NewRepairing}]}),
|
||||||
|
|
||||||
P = machi_projection:new(OldEpochNum + 1,
|
P0 = machi_projection:new(OldEpochNum + 1,
|
||||||
MyName, MembersDict, Down, NewUPI, NewRepairing,
|
MyName, MembersDict, Down, NewUPI, NewRepairing,
|
||||||
D_foo ++
|
D_foo ++
|
||||||
Dbg ++ [{ps, Partitions},{nodes_up, Up}]),
|
Dbg ++ [{ps, Partitions},{nodes_up, Up}]),
|
||||||
|
P1 = P0#projection_v1{chain_name=ChainName},
|
||||||
P2 = if CMode == cp_mode ->
|
P2 = if CMode == cp_mode ->
|
||||||
UpWitnesses = [W || W <- Up, lists:member(W, OldWitness_list)],
|
UpWitnesses = [W || W <- Up, lists:member(W, OldWitness_list)],
|
||||||
Majority = full_majority_size(AllMembers),
|
Majority = full_majority_size(AllMembers),
|
||||||
|
@ -833,7 +847,7 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
SoFar = length(NewUPI ++ NewRepairing),
|
SoFar = length(NewUPI ++ NewRepairing),
|
||||||
if SoFar >= Majority ->
|
if SoFar >= Majority ->
|
||||||
?REACT({calc,?LINE,[]}),
|
?REACT({calc,?LINE,[]}),
|
||||||
P;
|
P1;
|
||||||
true ->
|
true ->
|
||||||
Need = Majority - SoFar,
|
Need = Majority - SoFar,
|
||||||
UpWitnesses = [W || W <- Up,
|
UpWitnesses = [W || W <- Up,
|
||||||
|
@ -842,7 +856,7 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
Ws = lists:sublist(UpWitnesses, Need),
|
Ws = lists:sublist(UpWitnesses, Need),
|
||||||
?REACT({calc,?LINE,[{ws, Ws}]}),
|
?REACT({calc,?LINE,[{ws, Ws}]}),
|
||||||
machi_projection:update_checksum(
|
machi_projection:update_checksum(
|
||||||
P#projection_v1{upi=Ws++NewUPI});
|
P1#projection_v1{upi=Ws++NewUPI});
|
||||||
true ->
|
true ->
|
||||||
?REACT({calc,?LINE,[]}),
|
?REACT({calc,?LINE,[]}),
|
||||||
P_none0 = make_none_projection(
|
P_none0 = make_none_projection(
|
||||||
|
@ -855,6 +869,7 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
"Not enough witnesses are available now"
|
"Not enough witnesses are available now"
|
||||||
end,
|
end,
|
||||||
P_none1 = P_none0#projection_v1{
|
P_none1 = P_none0#projection_v1{
|
||||||
|
chain_name=ChainName,
|
||||||
%% Stable creation time!
|
%% Stable creation time!
|
||||||
creation_time={1,2,3},
|
creation_time={1,2,3},
|
||||||
dbg=[{none_projection,true},
|
dbg=[{none_projection,true},
|
||||||
|
@ -875,7 +890,7 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
end;
|
end;
|
||||||
CMode == ap_mode ->
|
CMode == ap_mode ->
|
||||||
?REACT({calc,?LINE,[]}),
|
?REACT({calc,?LINE,[]}),
|
||||||
P
|
P1
|
||||||
end,
|
end,
|
||||||
P3 = machi_projection:update_checksum(
|
P3 = machi_projection:update_checksum(
|
||||||
P2#projection_v1{mode=CMode, witnesses=OldWitness_list}),
|
P2#projection_v1{mode=CMode, witnesses=OldWitness_list}),
|
||||||
|
@ -1045,7 +1060,7 @@ do_react_to_env(#ch_mgr{name=MyName,
|
||||||
{{empty_members_dict, [], Epoch}, S};
|
{{empty_members_dict, [], Epoch}, S};
|
||||||
true ->
|
true ->
|
||||||
{_, S2} = do_set_chain_members_dict(NewMembersDict, S),
|
{_, S2} = do_set_chain_members_dict(NewMembersDict, S),
|
||||||
CMode = calc_consistency_mode(NewProj#projection_v1.witnesses),
|
CMode = NewProj#projection_v1.mode,
|
||||||
{{empty_members_dict, [], Epoch},
|
{{empty_members_dict, [], Epoch},
|
||||||
set_proj(S2#ch_mgr{members_dict=NewMembersDict,
|
set_proj(S2#ch_mgr{members_dict=NewMembersDict,
|
||||||
consistency_mode=CMode}, NewProj)}
|
consistency_mode=CMode}, NewProj)}
|
||||||
|
@ -1287,7 +1302,8 @@ react_to_env_A29(Retries, P_latest, LatestUnanimousP, _ReadExtra,
|
||||||
end.
|
end.
|
||||||
|
|
||||||
react_to_env_A30(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
react_to_env_A30(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
||||||
#ch_mgr{name=MyName, consistency_mode=CMode} = S) ->
|
#ch_mgr{name=MyName, proj=P_current,
|
||||||
|
consistency_mode=CMode} = S) ->
|
||||||
V = case file:read_file("/tmp/moomoo."++atom_to_list(S#ch_mgr.name)) of {ok,_} -> true; _ -> false end,
|
V = case file:read_file("/tmp/moomoo."++atom_to_list(S#ch_mgr.name)) of {ok,_} -> true; _ -> false end,
|
||||||
if V -> io:format(user, "A30: ~w: ~p\n", [S#ch_mgr.name, get(react)]); true -> ok end,
|
if V -> io:format(user, "A30: ~w: ~p\n", [S#ch_mgr.name, get(react)]); true -> ok end,
|
||||||
?REACT(a30),
|
?REACT(a30),
|
||||||
|
@ -1307,15 +1323,17 @@ react_to_env_A30(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
||||||
P = #projection_v1{down=Down} =
|
P = #projection_v1{down=Down} =
|
||||||
make_none_projection(Epoch + 1, MyName, All_list,
|
make_none_projection(Epoch + 1, MyName, All_list,
|
||||||
Witness_list, MembersDict),
|
Witness_list, MembersDict),
|
||||||
|
ChainName = P_current#projection_v1.chain_name,
|
||||||
|
P1 = P#projection_v1{chain_name=ChainName},
|
||||||
P_newprop = if CMode == ap_mode ->
|
P_newprop = if CMode == ap_mode ->
|
||||||
%% Not really none proj: just myself, AP style
|
%% Not really none proj: just myself, AP style
|
||||||
machi_projection:update_checksum(
|
machi_projection:update_checksum(
|
||||||
P#projection_v1{upi=[MyName],
|
P1#projection_v1{upi=[MyName],
|
||||||
down=Down -- [MyName],
|
down=Down -- [MyName],
|
||||||
dbg=[{hosed_list,AllHosed}]});
|
dbg=[{hosed_list,AllHosed}]});
|
||||||
CMode == cp_mode ->
|
CMode == cp_mode ->
|
||||||
machi_projection:update_checksum(
|
machi_projection:update_checksum(
|
||||||
P#projection_v1{dbg=[{hosed_list,AllHosed}]})
|
P1#projection_v1{dbg=[{hosed_list,AllHosed}]})
|
||||||
end,
|
end,
|
||||||
react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
P_current_calc, true, S);
|
P_current_calc, true, S);
|
||||||
|
@ -1850,7 +1868,9 @@ react_to_env_C103(#projection_v1{epoch_number=_Epoch_newprop} = _P_newprop,
|
||||||
members_dict=MembersDict} = P_current,
|
members_dict=MembersDict} = P_current,
|
||||||
P_none0 = make_none_projection(Epoch_latest,
|
P_none0 = make_none_projection(Epoch_latest,
|
||||||
MyName, All_list, Witness_list, MembersDict),
|
MyName, All_list, Witness_list, MembersDict),
|
||||||
P_none1 = P_none0#projection_v1{dbg=[{none_projection,true}]},
|
ChainName = P_current#projection_v1.chain_name,
|
||||||
|
P_none1 = P_none0#projection_v1{chain_name=ChainName,
|
||||||
|
dbg=[{none_projection,true}]},
|
||||||
P_none = machi_projection:update_checksum(P_none1),
|
P_none = machi_projection:update_checksum(P_none1),
|
||||||
?REACT({c103, ?LINE,
|
?REACT({c103, ?LINE,
|
||||||
[{current_epoch, P_current#projection_v1.epoch_number},
|
[{current_epoch, P_current#projection_v1.epoch_number},
|
||||||
|
@ -2206,6 +2226,7 @@ projection_transition_is_sane_except_si_epoch(
|
||||||
creation_time=CreationTime1,
|
creation_time=CreationTime1,
|
||||||
mode=CMode1,
|
mode=CMode1,
|
||||||
author_server=AuthorServer1,
|
author_server=AuthorServer1,
|
||||||
|
chain_name=ChainName1,
|
||||||
all_members=All_list1,
|
all_members=All_list1,
|
||||||
witnesses=Witness_list1,
|
witnesses=Witness_list1,
|
||||||
down=Down_list1,
|
down=Down_list1,
|
||||||
|
@ -2217,6 +2238,7 @@ projection_transition_is_sane_except_si_epoch(
|
||||||
creation_time=CreationTime2,
|
creation_time=CreationTime2,
|
||||||
mode=CMode2,
|
mode=CMode2,
|
||||||
author_server=AuthorServer2,
|
author_server=AuthorServer2,
|
||||||
|
chain_name=ChainName2,
|
||||||
all_members=All_list2,
|
all_members=All_list2,
|
||||||
witnesses=Witness_list2,
|
witnesses=Witness_list2,
|
||||||
down=Down_list2,
|
down=Down_list2,
|
||||||
|
@ -2237,7 +2259,8 @@ projection_transition_is_sane_except_si_epoch(
|
||||||
true = is_binary(CSum1) andalso is_binary(CSum2),
|
true = is_binary(CSum1) andalso is_binary(CSum2),
|
||||||
{_,_,_} = CreationTime1,
|
{_,_,_} = CreationTime1,
|
||||||
{_,_,_} = CreationTime2,
|
{_,_,_} = CreationTime2,
|
||||||
true = is_atom(AuthorServer1) andalso is_atom(AuthorServer2), % todo type may change?
|
true = is_atom(AuthorServer1) andalso is_atom(AuthorServer2),
|
||||||
|
true = is_atom(ChainName1) andalso is_atom(ChainName2),
|
||||||
true = is_list(All_list1) andalso is_list(All_list2),
|
true = is_list(All_list1) andalso is_list(All_list2),
|
||||||
true = is_list(Witness_list1) andalso is_list(Witness_list2),
|
true = is_list(Witness_list1) andalso is_list(Witness_list2),
|
||||||
true = is_list(Down_list1) andalso is_list(Down_list2),
|
true = is_list(Down_list1) andalso is_list(Down_list2),
|
||||||
|
@ -2249,6 +2272,9 @@ projection_transition_is_sane_except_si_epoch(
|
||||||
%% projection_transition_is_sane_with_si_epoch().
|
%% projection_transition_is_sane_with_si_epoch().
|
||||||
true = Epoch2 >= Epoch1,
|
true = Epoch2 >= Epoch1,
|
||||||
|
|
||||||
|
%% Don't change chain names in the middle of the stream.
|
||||||
|
true = (ChainName1 == ChainName2),
|
||||||
|
|
||||||
%% No duplicates
|
%% No duplicates
|
||||||
true = lists:sort(Witness_list2) == lists:usort(Witness_list2),
|
true = lists:sort(Witness_list2) == lists:usort(Witness_list2),
|
||||||
true = lists:sort(Down_list2) == lists:usort(Down_list2),
|
true = lists:sort(Down_list2) == lists:usort(Down_list2),
|
||||||
|
@ -2772,6 +2798,7 @@ full_majority_size(L) when is_list(L) ->
|
||||||
full_majority_size(length(L)).
|
full_majority_size(length(L)).
|
||||||
|
|
||||||
make_zerf(#projection_v1{epoch_number=OldEpochNum,
|
make_zerf(#projection_v1{epoch_number=OldEpochNum,
|
||||||
|
chain_name=ChainName,
|
||||||
all_members=AllMembers,
|
all_members=AllMembers,
|
||||||
members_dict=MembersDict,
|
members_dict=MembersDict,
|
||||||
witnesses=OldWitness_list
|
witnesses=OldWitness_list
|
||||||
|
@ -2794,7 +2821,8 @@ make_zerf(#projection_v1{epoch_number=OldEpochNum,
|
||||||
MyName, AllMembers, OldWitness_list,
|
MyName, AllMembers, OldWitness_list,
|
||||||
MembersDict),
|
MembersDict),
|
||||||
machi_projection:update_checksum(
|
machi_projection:update_checksum(
|
||||||
P#projection_v1{mode=cp_mode,
|
P#projection_v1{chain_name=ChainName,
|
||||||
|
mode=cp_mode,
|
||||||
dbg2=[zerf_none,{up,Up},{maj,MajoritySize}]});
|
dbg2=[zerf_none,{up,Up},{maj,MajoritySize}]});
|
||||||
true ->
|
true ->
|
||||||
make_zerf2(OldEpochNum, Up, MajoritySize, MyName,
|
make_zerf2(OldEpochNum, Up, MajoritySize, MyName,
|
||||||
|
@ -2916,11 +2944,6 @@ perhaps_verbose_c111(P_latest2, S) ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
calc_consistency_mode(_Witness_list = []) ->
|
|
||||||
ap_mode;
|
|
||||||
calc_consistency_mode(_Witness_list) ->
|
|
||||||
cp_mode.
|
|
||||||
|
|
||||||
set_proj(S, Proj) ->
|
set_proj(S, Proj) ->
|
||||||
S#ch_mgr{proj=Proj, proj_unanimous=false}.
|
S#ch_mgr{proj=Proj, proj_unanimous=false}.
|
||||||
|
|
||||||
|
|
|
@ -811,6 +811,7 @@ conv_to_epoch_id(#mpb_epochid{epoch_number=Epoch,
|
||||||
conv_to_projection_v1(#mpb_projectionv1{epoch_number=Epoch,
|
conv_to_projection_v1(#mpb_projectionv1{epoch_number=Epoch,
|
||||||
epoch_csum=CSum,
|
epoch_csum=CSum,
|
||||||
author_server=Author,
|
author_server=Author,
|
||||||
|
chain_name=ChainName,
|
||||||
all_members=AllMembers,
|
all_members=AllMembers,
|
||||||
witnesses=Witnesses,
|
witnesses=Witnesses,
|
||||||
creation_time=CTime,
|
creation_time=CTime,
|
||||||
|
@ -824,6 +825,7 @@ conv_to_projection_v1(#mpb_projectionv1{epoch_number=Epoch,
|
||||||
#projection_v1{epoch_number=Epoch,
|
#projection_v1{epoch_number=Epoch,
|
||||||
epoch_csum=CSum,
|
epoch_csum=CSum,
|
||||||
author_server=to_atom(Author),
|
author_server=to_atom(Author),
|
||||||
|
chain_name=to_atom(ChainName),
|
||||||
all_members=[to_atom(X) || X <- AllMembers],
|
all_members=[to_atom(X) || X <- AllMembers],
|
||||||
witnesses=[to_atom(X) || X <- Witnesses],
|
witnesses=[to_atom(X) || X <- Witnesses],
|
||||||
creation_time=conv_to_now(CTime),
|
creation_time=conv_to_now(CTime),
|
||||||
|
@ -971,6 +973,7 @@ conv_from_boolean(true) ->
|
||||||
conv_from_projection_v1(#projection_v1{epoch_number=Epoch,
|
conv_from_projection_v1(#projection_v1{epoch_number=Epoch,
|
||||||
epoch_csum=CSum,
|
epoch_csum=CSum,
|
||||||
author_server=Author,
|
author_server=Author,
|
||||||
|
chain_name=ChainName,
|
||||||
all_members=AllMembers,
|
all_members=AllMembers,
|
||||||
witnesses=Witnesses,
|
witnesses=Witnesses,
|
||||||
creation_time=CTime,
|
creation_time=CTime,
|
||||||
|
@ -984,6 +987,7 @@ conv_from_projection_v1(#projection_v1{epoch_number=Epoch,
|
||||||
#mpb_projectionv1{epoch_number=Epoch,
|
#mpb_projectionv1{epoch_number=Epoch,
|
||||||
epoch_csum=CSum,
|
epoch_csum=CSum,
|
||||||
author_server=to_list(Author),
|
author_server=to_list(Author),
|
||||||
|
chain_name=to_list(ChainName),
|
||||||
all_members=[to_list(X) || X <- AllMembers],
|
all_members=[to_list(X) || X <- AllMembers],
|
||||||
witnesses=[to_list(X) || X <- Witnesses],
|
witnesses=[to_list(X) || X <- Witnesses],
|
||||||
creation_time=conv_from_now(CTime),
|
creation_time=conv_from_now(CTime),
|
||||||
|
|
|
@ -407,7 +407,7 @@ stabilize(0, _T) ->
|
||||||
stabilize(_CmdsLen, #target{flu_names=FLUNames, mgr_names=MgrNames,
|
stabilize(_CmdsLen, #target{flu_names=FLUNames, mgr_names=MgrNames,
|
||||||
verbose=Verbose}) ->
|
verbose=Verbose}) ->
|
||||||
machi_partition_simulator:no_partitions(),
|
machi_partition_simulator:no_partitions(),
|
||||||
wait_until_stable(chain_state_all_ok(FLUNames), FLUNames, MgrNames,
|
true = wait_until_stable(chain_state_all_ok(FLUNames), FLUNames, MgrNames,
|
||||||
100, Verbose),
|
100, Verbose),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
|
@ -187,15 +187,18 @@ convergence_demo_testfun(NumFLUs, MgrOpts0) ->
|
||||||
end || #p_srvr{name=Name}=P <- Ps],
|
end || #p_srvr{name=Name}=P <- Ps],
|
||||||
MembersDict = machi_projection:make_members_dict(Ps),
|
MembersDict = machi_projection:make_members_dict(Ps),
|
||||||
Witnesses = proplists:get_value(witnesses, MgrOpts, []),
|
Witnesses = proplists:get_value(witnesses, MgrOpts, []),
|
||||||
|
CMode = case {Witnesses, proplists:get_value(consistency_mode, MgrOpts,
|
||||||
|
ap_mode)} of
|
||||||
|
{[_|_], _} -> cp_mode;
|
||||||
|
{_, cp_mode} -> cp_mode;
|
||||||
|
{_, ap_mode} -> ap_mode
|
||||||
|
end,
|
||||||
MgrNamez = [begin
|
MgrNamez = [begin
|
||||||
MgrName = machi_flu_psup:make_mgr_supname(Name),
|
MgrName = machi_flu_psup:make_mgr_supname(Name),
|
||||||
ok = ?MGR:set_chain_members(MgrName,MembersDict,Witnesses),
|
ok = ?MGR:set_chain_members(MgrName, ch_demo, 0, CMode,
|
||||||
|
MembersDict,Witnesses),
|
||||||
{Name, MgrName}
|
{Name, MgrName}
|
||||||
end || #p_srvr{name=Name} <- Ps],
|
end || #p_srvr{name=Name} <- Ps],
|
||||||
CpApMode = case Witnesses /= [] of
|
|
||||||
true -> cp_mode;
|
|
||||||
false -> ap_mode
|
|
||||||
end,
|
|
||||||
|
|
||||||
try
|
try
|
||||||
[{_, Ma}|_] = MgrNamez,
|
[{_, Ma}|_] = MgrNamez,
|
||||||
|
@ -303,9 +306,9 @@ convergence_demo_testfun(NumFLUs, MgrOpts0) ->
|
||||||
[{FLU, true} = {FLU, ?MGR:projection_transitions_are_sane_retrospective(Psx, FLU)} ||
|
[{FLU, true} = {FLU, ?MGR:projection_transitions_are_sane_retrospective(Psx, FLU)} ||
|
||||||
{FLU, Psx} <- PrivProjs]
|
{FLU, Psx} <- PrivProjs]
|
||||||
catch
|
catch
|
||||||
_Err:_What when CpApMode == cp_mode ->
|
_Err:_What when CMode == cp_mode ->
|
||||||
io:format(user, "none proj skip detected, TODO? ", []);
|
io:format(user, "none proj skip detected, TODO? ", []);
|
||||||
_Err:_What when CpApMode == ap_mode ->
|
_Err:_What when CMode == ap_mode ->
|
||||||
io:format(user, "PrivProjs ~p\n", [PrivProjs]),
|
io:format(user, "PrivProjs ~p\n", [PrivProjs]),
|
||||||
exit({line, ?LINE, _Err, _What})
|
exit({line, ?LINE, _Err, _What})
|
||||||
end,
|
end,
|
||||||
|
@ -371,9 +374,9 @@ timer:sleep(1234),
|
||||||
{FLU, Psx} <- PrivProjs],
|
{FLU, Psx} <- PrivProjs],
|
||||||
io:format(user, "\nAll sanity checks pass, hooray!\n", [])
|
io:format(user, "\nAll sanity checks pass, hooray!\n", [])
|
||||||
catch
|
catch
|
||||||
_Err:_What when CpApMode == cp_mode ->
|
_Err:_What when CMode == cp_mode ->
|
||||||
io:format(user, "none proj skip detected, TODO? ", []);
|
io:format(user, "none proj skip detected, TODO? ", []);
|
||||||
_Err:_What when CpApMode == ap_mode ->
|
_Err:_What when CMode == ap_mode ->
|
||||||
io:format(user, "Report ~p\n", [Report]),
|
io:format(user, "Report ~p\n", [Report]),
|
||||||
io:format(user, "PrivProjs ~p\n", [PrivProjs]),
|
io:format(user, "PrivProjs ~p\n", [PrivProjs]),
|
||||||
exit({line, ?LINE, _Err, _What})
|
exit({line, ?LINE, _Err, _What})
|
||||||
|
|
|
@ -349,8 +349,8 @@ nonunanimous_setup_and_fix_test() ->
|
||||||
[element(2,?FLU_PC:start_link(P)) || P <- P_s],
|
[element(2,?FLU_PC:start_link(P)) || P <- P_s],
|
||||||
MembersDict = machi_projection:make_members_dict(P_s),
|
MembersDict = machi_projection:make_members_dict(P_s),
|
||||||
[Ma,Mb] = [a_chmgr, b_chmgr],
|
[Ma,Mb] = [a_chmgr, b_chmgr],
|
||||||
ok = machi_chain_manager1:set_chain_members(Ma, MembersDict, []),
|
ok = machi_chain_manager1:set_chain_members(Ma, MembersDict),
|
||||||
ok = machi_chain_manager1:set_chain_members(Mb, MembersDict, []),
|
ok = machi_chain_manager1:set_chain_members(Mb, MembersDict),
|
||||||
try
|
try
|
||||||
{ok, P1} = ?MGR:test_calc_projection(Ma, false),
|
{ok, P1} = ?MGR:test_calc_projection(Ma, false),
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,15 @@ setup_smoke_test(Host, PortBase, Os, Witness_list) ->
|
||||||
%% 4. Wait until all others are using epoch id from #3.
|
%% 4. Wait until all others are using epoch id from #3.
|
||||||
%%
|
%%
|
||||||
%% Damn, this is a pain to make 100% deterministic, bleh.
|
%% Damn, this is a pain to make 100% deterministic, bleh.
|
||||||
ok = machi_chain_manager1:set_chain_members(a_chmgr, D, Witness_list),
|
CMode = if Witness_list == [] -> ap_mode;
|
||||||
ok = machi_chain_manager1:set_chain_members(b_chmgr, D, Witness_list),
|
Witness_list /= [] -> cp_mode
|
||||||
ok = machi_chain_manager1:set_chain_members(c_chmgr, D, Witness_list),
|
end,
|
||||||
|
ok = machi_chain_manager1:set_chain_members(a_chmgr, ch0, 0, CMode,
|
||||||
|
D, Witness_list),
|
||||||
|
ok = machi_chain_manager1:set_chain_members(b_chmgr, ch0, 0, CMode,
|
||||||
|
D, Witness_list),
|
||||||
|
ok = machi_chain_manager1:set_chain_members(c_chmgr, ch0, 0, CMode,
|
||||||
|
D, Witness_list),
|
||||||
run_ticks([a_chmgr,b_chmgr,c_chmgr]),
|
run_ticks([a_chmgr,b_chmgr,c_chmgr]),
|
||||||
%% Everyone is settled on the same damn epoch id.
|
%% Everyone is settled on the same damn epoch id.
|
||||||
{ok, EpochID} = machi_flu1_client:get_latest_epochid(Host, PortBase+0,
|
{ok, EpochID} = machi_flu1_client:get_latest_epochid(Host, PortBase+0,
|
||||||
|
|
Loading…
Reference in a new issue