Bugfix: epoch handling around none proj: epoch 0 only at first bootstrap!

This commit is contained in:
Scott Lystig Fritchie 2015-08-30 19:53:47 +09:00
parent 823b47bef3
commit a449025e8b

View file

@ -235,7 +235,7 @@ init({MyName, InitMembersDict, MgrOpts}) ->
Opt = fun(Key, Default) -> proplists:get_value(Key, MgrOpts, Default) end, Opt = fun(Key, Default) -> proplists:get_value(Key, MgrOpts, Default) end,
InitWitness_list = Opt(witnesses, []), InitWitness_list = Opt(witnesses, []),
ZeroAll_list = [P#p_srvr.name || {_,P} <- orddict:to_list(InitMembersDict)], ZeroAll_list = [P#p_srvr.name || {_,P} <- orddict:to_list(InitMembersDict)],
ZeroProj = make_none_projection(MyName, ZeroAll_list, ZeroProj = make_none_projection(0, MyName, ZeroAll_list,
InitWitness_list, InitMembersDict), InitWitness_list, InitMembersDict),
ok = store_zeroth_projection_maybe(ZeroProj, MgrOpts), ok = store_zeroth_projection_maybe(ZeroProj, MgrOpts),
CMode = Opt(consistency_mode, ap_mode), CMode = Opt(consistency_mode, ap_mode),
@ -262,9 +262,8 @@ init({MyName, InitMembersDict, MgrOpts}) ->
get_my_private_proj_boot_info(MgrOpts, InitMembersDict, ZeroProj), get_my_private_proj_boot_info(MgrOpts, InitMembersDict, ZeroProj),
#projection_v1{epoch_number=CurrentEpoch, #projection_v1{epoch_number=CurrentEpoch,
all_members=All_list, witnesses=Witness_list} = Proj0, all_members=All_list, witnesses=Witness_list} = Proj0,
Proj1 = make_none_projection(MyName, All_list, Witness_list, MembersDict), Proj = make_none_projection(CurrentEpoch,
Proj = machi_projection:update_checksum( MyName, All_list, Witness_list, MembersDict),
Proj1#projection_v1{epoch_number=CurrentEpoch}),
RunEnv = [{seed, Opt(seed, now())}, RunEnv = [{seed, Opt(seed, now())},
{use_partition_simulator, Opt(use_partition_simulator, false)}, {use_partition_simulator, Opt(use_partition_simulator, false)},
@ -407,7 +406,7 @@ code_change(_OldVsn, S, _Extra) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
make_none_projection(MyName, All_list, Witness_list, MembersDict) -> make_none_projection(Epoch, MyName, All_list, Witness_list, MembersDict) ->
Down_list = All_list, Down_list = All_list,
UPI_list = [], UPI_list = [],
P = machi_projection:new(MyName, MembersDict, Down_list, UPI_list, [], []), P = machi_projection:new(MyName, MembersDict, Down_list, UPI_list, [], []),
@ -416,7 +415,8 @@ make_none_projection(MyName, All_list, Witness_list, MembersDict) ->
Witness_list /= [] -> Witness_list /= [] ->
cp_mode cp_mode
end, end,
machi_projection:update_checksum(P#projection_v1{mode=CMode, machi_projection:update_checksum(P#projection_v1{epoch_number=Epoch,
mode=CMode,
witnesses=Witness_list}). witnesses=Witness_list}).
make_all_projection(MyName, All_list, Witness_list, MembersDict) -> make_all_projection(MyName, All_list, Witness_list, MembersDict) ->
@ -587,7 +587,7 @@ rank_and_sort_projections_with_extra(All_queried_list, FLUsRs, ProjectionType,
orelse orelse
length(UnwrittenRs) == length(FLUsRs) -> length(UnwrittenRs) == length(FLUsRs) ->
Witness_list = CurrentProj#projection_v1.witnesses, Witness_list = CurrentProj#projection_v1.witnesses,
NoneProj = make_none_projection(MyName, [], Witness_list, NoneProj = make_none_projection(0, MyName, [], Witness_list,
orddict:new()), orddict:new()),
Extra2 = [{all_members_replied, true}, Extra2 = [{all_members_replied, true},
{all_queried_list, All_queried_list}, {all_queried_list, All_queried_list},
@ -708,7 +708,8 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
NewUp = Up -- LastUp, NewUp = Up -- LastUp,
Down = AllMembers -- Up, Down = AllMembers -- Up,
?REACT({calc,?LINE,[{old_upi, OldUPI_list}, ?REACT({calc,?LINE,[{old_epoch,OldEpochNum},
{old_upi, OldUPI_list},
{old_repairing,OldRepairing_list}, {old_repairing,OldRepairing_list},
{last_up, LastUp}, {up0, Up0}, {all_hosed, AllHosed}, {last_up, LastUp}, {up0, Up0}, {all_hosed, AllHosed},
{up, Up}, {new_up, NewUp}, {down, Down}]}), {up, Up}, {new_up, NewUp}, {down, Down}]}),
@ -818,6 +819,7 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
true -> true ->
?REACT({calc,?LINE,[]}), ?REACT({calc,?LINE,[]}),
P_none0 = make_none_projection( P_none0 = make_none_projection(
OldEpochNum + 1,
MyName, AllMembers, OldWitness_list, MyName, AllMembers, OldWitness_list,
MembersDict), MembersDict),
Why = if NewUPI == [] -> Why = if NewUPI == [] ->
@ -826,7 +828,6 @@ 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{
epoch_number=OldEpochNum + 1,
%% Stable creation time! %% Stable creation time!
creation_time={1,2,3}, creation_time={1,2,3},
dbg=[{none_projection,true}, dbg=[{none_projection,true},
@ -1707,7 +1708,8 @@ react_to_env_A49(_P_latest, FinalProps, #ch_mgr{name=MyName,
#projection_v1{all_members=All_list, #projection_v1{all_members=All_list,
witnesses=Witness_list, witnesses=Witness_list,
members_dict=MembersDict} = P_current, members_dict=MembersDict} = P_current,
P_none = make_none_projection(MyName, All_list, Witness_list, #projection_v1{epoch_number=EpochCurrent} = P_current,
P_none = make_none_projection(EpochCurrent, MyName, All_list, Witness_list,
MembersDict), MembersDict),
react_to_env_A50(P_none, FinalProps, set_proj(S, P_none)). react_to_env_A50(P_none, FinalProps, set_proj(S, P_none)).
@ -1716,6 +1718,7 @@ react_to_env_A50(P_latest, FinalProps, #ch_mgr{proj=P_current}=S) ->
?REACT({a50, ?LINE, [{current_epoch, P_current#projection_v1.epoch_number}, ?REACT({a50, ?LINE, [{current_epoch, P_current#projection_v1.epoch_number},
{latest_epoch, P_latest#projection_v1.epoch_number}, {latest_epoch, P_latest#projection_v1.epoch_number},
{final_props, FinalProps}]}), {final_props, FinalProps}]}),
%% if S#ch_mgr.name == c -> io:format(user, "A50: ~w: ~p\n", [S#ch_mgr.name, get(react)]); true -> ok end,
{{no_change, FinalProps, P_current#projection_v1.epoch_number}, S}. {{no_change, FinalProps, P_current#projection_v1.epoch_number}, S}.
react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP, react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP,
@ -2036,9 +2039,9 @@ react_to_env_C103(#projection_v1{epoch_number=_Epoch_newprop} = _P_newprop,
#ch_mgr{name=MyName, proj=P_current}=S) -> #ch_mgr{name=MyName, proj=P_current}=S) ->
#projection_v1{witnesses=Witness_list, #projection_v1{witnesses=Witness_list,
members_dict=MembersDict} = P_current, members_dict=MembersDict} = P_current,
P_none0 = make_none_projection(MyName, All_list, Witness_list, MembersDict), P_none0 = make_none_projection(Epoch_latest,
P_none1 = P_none0#projection_v1{epoch_number=Epoch_latest, MyName, All_list, Witness_list, MembersDict),
flap=Flap, P_none1 = P_none0#projection_v1{flap=Flap,
dbg=[{none_projection,true}]}, dbg=[{none_projection,true}]},
P_none = machi_projection:update_checksum(P_none1), P_none = machi_projection:update_checksum(P_none1),
%% Use it, darn it, because it's 100% safe. And exit flapping state. %% Use it, darn it, because it's 100% safe. And exit flapping state.
@ -2616,7 +2619,7 @@ projection_transition_is_sane_final_review(
{wtf, cmode1, CMode1, cmode2, CMode2}; {wtf, cmode1, CMode1, cmode2, CMode2};
projection_transition_is_sane_final_review( projection_transition_is_sane_final_review(
#projection_v1{mode=cp_mode, upi=UPI1}=_P1, #projection_v1{mode=cp_mode, upi=UPI1}=_P1,
#projection_v1{mode=cp_mode, upi=UPI2, witnesses=Witness_list, dbg=Dbg2}=_P2, #projection_v1{mode=cp_mode, upi=UPI2, witnesses=Witness_list, dbg=Dbg}=_P2,
true) -> true) ->
%% All earlier sanity checks has said that this transition is sane, but %% All earlier sanity checks has said that this transition is sane, but
%% we also need to make certain that any CP mode transition preserves at %% we also need to make certain that any CP mode transition preserves at
@ -2624,7 +2627,11 @@ projection_transition_is_sane_final_review(
%% verified that the ordering of the FLUs within the UPI list is ok. %% verified that the ordering of the FLUs within the UPI list is ok.
UPI1_s = ordsets:from_list(UPI1 -- Witness_list), UPI1_s = ordsets:from_list(UPI1 -- Witness_list),
UPI2_s = ordsets:from_list(UPI2 -- Witness_list), UPI2_s = ordsets:from_list(UPI2 -- Witness_list),
case proplists:get_value(zerf_backstop, Dbg2) of catch ?REACT({projection_transition_is_sane_final_review, ?LINE,
[{upi1,UPI1}, {upi2,UPI2}, {witnesses,Witness_list},
{zerf_backstop, proplists:get_value(zerf_backstop, Dbg)},
{upi1_s,UPI1}, {upi2_s,UPI2}]}),
case proplists:get_value(zerf_backstop, Dbg) of
true when UPI1 == [] -> true when UPI1 == [] ->
?RETURN2(true); ?RETURN2(true);
_ when UPI2 == [] -> _ when UPI2 == [] ->
@ -3316,11 +3323,11 @@ make_zerf(#projection_v1{epoch_number=OldEpochNum,
%% zerf_find_last_common() can confirm a common stable %% zerf_find_last_common() can confirm a common stable
%% last stable epoch. %% last stable epoch.
P = make_none_projection(MyName, AllMembers, OldWitness_list, P = make_none_projection(OldEpochNum,
MyName, AllMembers, OldWitness_list,
MembersDict), MembersDict),
machi_projection:update_checksum( machi_projection:update_checksum(
P#projection_v1{epoch_number=OldEpochNum, P#projection_v1{mode=cp_mode,
mode=cp_mode,
flap=OldFlap, flap=OldFlap,
dbg2=[zerf_none,{up,Up},{maj,MajoritySize}]}); dbg2=[zerf_none,{up,Up},{maj,MajoritySize}]});
true -> true ->