Yeah, nearly there. AP fails occasionally in multiple-asymmetric-partition sequence
This commit is contained in:
parent
72141c8ecb
commit
b7aa33c617
3 changed files with 90 additions and 38 deletions
|
@ -1202,13 +1202,37 @@ 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} = S) ->
|
#ch_mgr{name=MyName, consistency_mode=CMode} = S) ->
|
||||||
?REACT(a30),
|
?REACT(a30),
|
||||||
AllHosed = get_unfit_list(S#ch_mgr.fitness_svr),
|
AllHosed = get_unfit_list(S#ch_mgr.fitness_svr),
|
||||||
?REACT({a30, ?LINE, [{all_hosed, AllHosed}]}),
|
?REACT({a30, ?LINE,
|
||||||
|
[{current, machi_projection:make_summary(S#ch_mgr.proj)},
|
||||||
|
{calc_current, machi_projection:make_summary(P_current_calc)},
|
||||||
|
{latest, machi_projection:make_summary(P_latest)},
|
||||||
|
{all_hosed, AllHosed}
|
||||||
|
]}),
|
||||||
|
?REACT({a30, ?LINE, []}),
|
||||||
case lists:member(MyName, AllHosed) of
|
case lists:member(MyName, AllHosed) of
|
||||||
true ->
|
true ->
|
||||||
react_to_env_A50(P_latest, [{i_am_hosed, AllHosed}], S);
|
io:format(user, "AmHosed: ~w, ", [MyName]),
|
||||||
|
#projection_v1{epoch_number=Epoch, all_members=All_list,
|
||||||
|
witnesses=Witness_list,
|
||||||
|
members_dict=MembersDict} = P_latest,
|
||||||
|
P = #projection_v1{down=Down} =
|
||||||
|
make_none_projection(Epoch + 1, MyName, All_list,
|
||||||
|
Witness_list, MembersDict),
|
||||||
|
P_newprop = if CMode == ap_mode ->
|
||||||
|
%% Not really none proj: just myself, AP style
|
||||||
|
machi_projection:update_checksum(
|
||||||
|
P#projection_v1{upi=[MyName],
|
||||||
|
down=Down -- [MyName],
|
||||||
|
dbg=[{hosed_list,AllHosed}]});
|
||||||
|
CMode == cp_mode ->
|
||||||
|
machi_projection:update_checksum(
|
||||||
|
P#projection_v1{dbg=[{hosed_list,AllHosed}]})
|
||||||
|
end,
|
||||||
|
react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
|
true, S);
|
||||||
false ->
|
false ->
|
||||||
react_to_env_A31(Retries, P_latest, LatestUnanimousP,
|
react_to_env_A31(Retries, P_latest, LatestUnanimousP,
|
||||||
P_current_calc, AllHosed, S)
|
P_current_calc, AllHosed, S)
|
||||||
|
@ -1217,12 +1241,8 @@ react_to_env_A30(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
||||||
react_to_env_A31(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
react_to_env_A31(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
||||||
AllHosed, #ch_mgr{name=MyName} = S) ->
|
AllHosed, #ch_mgr{name=MyName} = S) ->
|
||||||
{P_newprop1, S2,_Up} = calc_projection(S, MyName, AllHosed, P_current_calc),
|
{P_newprop1, S2,_Up} = calc_projection(S, MyName, AllHosed, P_current_calc),
|
||||||
?REACT({a30, ?LINE,
|
?REACT({a31, ?LINE,
|
||||||
[{current, machi_projection:make_summary(S#ch_mgr.proj)},
|
[{newprop1, machi_projection:make_summary(P_newprop1)}]}),
|
||||||
{calc_current, machi_projection:make_summary(P_current_calc)},
|
|
||||||
{latest, machi_projection:make_summary(P_latest)},
|
|
||||||
{newprop1, machi_projection:make_summary(P_newprop1)}
|
|
||||||
]}),
|
|
||||||
|
|
||||||
{P_newprop2, S3} = {P_newprop1, S2},
|
{P_newprop2, S3} = {P_newprop1, S2},
|
||||||
|
|
||||||
|
@ -1231,14 +1251,14 @@ react_to_env_A31(Retries, P_latest, LatestUnanimousP, P_current_calc,
|
||||||
#projection_v1{epoch_number=Epoch_latest}=P_latest,
|
#projection_v1{epoch_number=Epoch_latest}=P_latest,
|
||||||
NewEpoch = erlang:max(Epoch_newprop2, Epoch_latest) + 1,
|
NewEpoch = erlang:max(Epoch_newprop2, Epoch_latest) + 1,
|
||||||
P_newprop3 = P_newprop2#projection_v1{epoch_number=NewEpoch},
|
P_newprop3 = P_newprop2#projection_v1{epoch_number=NewEpoch},
|
||||||
?REACT({a30, ?LINE, [{newprop3, machi_projection:make_summary(P_newprop3)}]}),
|
?REACT({a31, ?LINE, [{newprop3, machi_projection:make_summary(P_newprop3)}]}),
|
||||||
|
|
||||||
{P_newprop10, S10} = {P_newprop3, S3},
|
{P_newprop10, S10} = {P_newprop3, S3},
|
||||||
P_newprop11 = machi_projection:update_checksum(P_newprop10),
|
P_newprop11 = machi_projection:update_checksum(P_newprop10),
|
||||||
?REACT({a30, ?LINE, [{newprop11, machi_projection:make_summary(P_newprop11)}]}),
|
?REACT({a31, ?LINE, [{newprop11, machi_projection:make_summary(P_newprop11)}]}),
|
||||||
|
|
||||||
react_to_env_A40(Retries, P_newprop11, P_latest,
|
react_to_env_A40(Retries, P_newprop11, P_latest, LatestUnanimousP,
|
||||||
LatestUnanimousP, S10).
|
false, S10).
|
||||||
|
|
||||||
a40_latest_author_down(#projection_v1{author_server=LatestAuthor}=_P_latest,
|
a40_latest_author_down(#projection_v1{author_server=LatestAuthor}=_P_latest,
|
||||||
#projection_v1{upi=[], repairing=[],
|
#projection_v1{upi=[], repairing=[],
|
||||||
|
@ -1253,7 +1273,7 @@ a40_latest_author_down(#projection_v1{author_server=LatestAuthor}=_P_latest,
|
||||||
#projection_v1{down=NewPropDown}=_P_newprop, _S) ->
|
#projection_v1{down=NewPropDown}=_P_newprop, _S) ->
|
||||||
lists:member(LatestAuthor, NewPropDown).
|
lists:member(LatestAuthor, NewPropDown).
|
||||||
|
|
||||||
react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP, AmHosedP,
|
||||||
#ch_mgr{name=MyName, proj=P_current}=S) ->
|
#ch_mgr{name=MyName, proj=P_current}=S) ->
|
||||||
?REACT(a40),
|
?REACT(a40),
|
||||||
[{Rank_newprop, _}] = rank_projections([P_newprop], P_current),
|
[{Rank_newprop, _}] = rank_projections([P_newprop], P_current),
|
||||||
|
@ -1268,6 +1288,33 @@ react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
{author_is_down_p, LatestAuthorDownP}]}),
|
{author_is_down_p, LatestAuthorDownP}]}),
|
||||||
|
|
||||||
if
|
if
|
||||||
|
AmHosedP ->
|
||||||
|
if P_current#projection_v1.upi /= []
|
||||||
|
andalso
|
||||||
|
P_newprop#projection_v1.upi == [] ->
|
||||||
|
io:format(user, "TODO this clause needs more review!\n",[]),
|
||||||
|
%% This is a cp_mode case only.
|
||||||
|
%% I am hosed. I need to shut up and quit disturbing my
|
||||||
|
%% peers. If P_latest is the none projection that I wrote
|
||||||
|
%% on a previous iteration and it's also unanimous, then
|
||||||
|
%% go to B10 so that I can adopt it. Otherwise, tell the
|
||||||
|
%% world my intention via C300.
|
||||||
|
if P_latest#projection_v1.author_server == MyName andalso
|
||||||
|
P_latest#projection_v1.upi == [] andalso
|
||||||
|
LatestUnanimousP ->
|
||||||
|
?REACT({a40, ?LINE, []}),
|
||||||
|
react_to_env_B10(Retries, P_newprop, P_latest,
|
||||||
|
LatestUnanimousP,
|
||||||
|
AmHosedP, Rank_newprop, Rank_latest, S);
|
||||||
|
true ->
|
||||||
|
?REACT({a40, ?LINE, []}),
|
||||||
|
react_to_env_C300(P_newprop, P_latest, S)
|
||||||
|
end;
|
||||||
|
true ->
|
||||||
|
?REACT({a40, ?LINE, []}),
|
||||||
|
react_to_env_A50(P_latest, [], S)
|
||||||
|
end;
|
||||||
|
|
||||||
%% Epoch == 0 is reserved for first-time, just booting conditions.
|
%% Epoch == 0 is reserved for first-time, just booting conditions.
|
||||||
(Rank_newprop > 0 orelse (Rank_newprop == ?RANK_CP_MINORITY_QUORUM))
|
(Rank_newprop > 0 orelse (Rank_newprop == ?RANK_CP_MINORITY_QUORUM))
|
||||||
andalso
|
andalso
|
||||||
|
@ -1282,7 +1329,7 @@ react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
{latest_unanimous_p, LatestUnanimousP}]}),
|
{latest_unanimous_p, LatestUnanimousP}]}),
|
||||||
|
|
||||||
react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP,
|
react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
Rank_newprop, Rank_latest, S);
|
AmHosedP, Rank_newprop, Rank_latest, S);
|
||||||
|
|
||||||
Rank_newprop > 0
|
Rank_newprop > 0
|
||||||
andalso
|
andalso
|
||||||
|
@ -1313,7 +1360,7 @@ react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
%% I'm keeping this 'if' clause just in case the local FLU
|
%% I'm keeping this 'if' clause just in case the local FLU
|
||||||
%% projection store assumption changes.
|
%% projection store assumption changes.
|
||||||
react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP,
|
react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP,
|
||||||
Rank_newprop, Rank_latest, S);
|
AmHosedP, Rank_newprop, Rank_latest, S);
|
||||||
|
|
||||||
%% A40a (see flowchart)
|
%% A40a (see flowchart)
|
||||||
Rank_newprop > Rank_latest ->
|
Rank_newprop > Rank_latest ->
|
||||||
|
@ -1417,8 +1464,7 @@ react_to_env_A50(P_latest, FinalProps, #ch_mgr{proj=P_current}=S) ->
|
||||||
{{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,
|
||||||
Rank_newprop, Rank_latest,
|
AmHosedP, Rank_newprop, Rank_latest, #ch_mgr{name=MyName}=S) ->
|
||||||
#ch_mgr{name=MyName}=S)->
|
|
||||||
?REACT(b10),
|
?REACT(b10),
|
||||||
|
|
||||||
?REACT({b10,?LINE,[{newprop_epoch,P_newprop#projection_v1.epoch_number}]}),
|
?REACT({b10,?LINE,[{newprop_epoch,P_newprop#projection_v1.epoch_number}]}),
|
||||||
|
|
|
@ -67,6 +67,7 @@ send_fitness_update_spam(Pid, FromName, Dict) ->
|
||||||
init([{MyFluName}|_Args]) ->
|
init([{MyFluName}|_Args]) ->
|
||||||
RegName = machi_flu_psup:make_fitness_regname(MyFluName),
|
RegName = machi_flu_psup:make_fitness_regname(MyFluName),
|
||||||
register(RegName, self()),
|
register(RegName, self()),
|
||||||
|
timer:send_interval(1000, dump),
|
||||||
{ok, #state{my_flu_name=MyFluName, reg_name=RegName}}.
|
{ok, #state{my_flu_name=MyFluName, reg_name=RegName}}.
|
||||||
|
|
||||||
handle_call({get_unfit_list}, _From, #state{active_unfit=ActiveUnfit}=S) ->
|
handle_call({get_unfit_list}, _From, #state{active_unfit=ActiveUnfit}=S) ->
|
||||||
|
@ -98,6 +99,7 @@ handle_info({adjust_down_list, FLU}, #state{active_unfit=ActiveUnfit}=S) ->
|
||||||
NewUnfit = make_unfit_list(S),
|
NewUnfit = make_unfit_list(S),
|
||||||
Added_to_new = NewUnfit -- ActiveUnfit,
|
Added_to_new = NewUnfit -- ActiveUnfit,
|
||||||
Dropped_from_new = ActiveUnfit -- NewUnfit,
|
Dropped_from_new = ActiveUnfit -- NewUnfit,
|
||||||
|
io:format(user, "adjust_down_list: ~w: adjust ~w: add ~p drop ~p\n", [S#state.my_flu_name, FLU, Added_to_new, Dropped_from_new]),
|
||||||
case {lists:member(FLU,Added_to_new), lists:member(FLU,Dropped_from_new)} of
|
case {lists:member(FLU,Added_to_new), lists:member(FLU,Dropped_from_new)} of
|
||||||
{true, true} ->
|
{true, true} ->
|
||||||
error({bad, ?MODULE, ?LINE, FLU, ActiveUnfit, NewUnfit});
|
error({bad, ?MODULE, ?LINE, FLU, ActiveUnfit, NewUnfit});
|
||||||
|
@ -108,6 +110,10 @@ handle_info({adjust_down_list, FLU}, #state{active_unfit=ActiveUnfit}=S) ->
|
||||||
{false, false} ->
|
{false, false} ->
|
||||||
{noreply, S}
|
{noreply, S}
|
||||||
end;
|
end;
|
||||||
|
handle_info(dump, #state{my_flu_name=MyFluName,active_unfit=ActiveUnfit,
|
||||||
|
pending_map=Map}=S) ->
|
||||||
|
io:format(user, "DUMP: ~w: ~p ~w\n", [MyFluName, ActiveUnfit, map_value(Map)]),
|
||||||
|
{noreply, S};
|
||||||
handle_info(_Info, S) ->
|
handle_info(_Info, S) ->
|
||||||
{noreply, S}.
|
{noreply, S}.
|
||||||
|
|
||||||
|
|
|
@ -380,28 +380,28 @@ convergence_demo_testfun(NumFLUs, MgrOpts0) ->
|
||||||
%% Uncomment *one* of the following make_partition_list() bodies.
|
%% Uncomment *one* of the following make_partition_list() bodies.
|
||||||
|
|
||||||
make_partition_list(All_list) ->
|
make_partition_list(All_list) ->
|
||||||
Island1 = [hd(All_list), lists:last(All_list)],
|
%% Island1 = [hd(All_list), lists:last(All_list)],
|
||||||
Island2 = All_list -- Island1,
|
%% Island2 = All_list -- Island1,
|
||||||
[
|
%% [
|
||||||
[{X,Y} || X <- Island1, Y <- Island2]
|
%% [{X,Y} || X <- Island1, Y <- Island2]
|
||||||
++
|
%% ++
|
||||||
[{X,Y} || X <- Island2, Y <- Island1]
|
%% [{X,Y} || X <- Island2, Y <- Island1]
|
||||||
].
|
%% ].
|
||||||
|
|
||||||
%% _X_Ys1 = [[{X,Y}] || X <- All_list, Y <- All_list, X /= Y],
|
_X_Ys1 = [[{X,Y}] || X <- All_list, Y <- All_list, X /= Y],
|
||||||
%% _X_Ys2 = [[{X,Y}, {A,B}] || X <- All_list, Y <- All_list, X /= Y,
|
_X_Ys2 = [[{X,Y}, {A,B}] || X <- All_list, Y <- All_list, X /= Y,
|
||||||
%% A <- All_list, B <- All_list, A /= B,
|
A <- All_list, B <- All_list, A /= B,
|
||||||
%% X /= A],
|
X /= A],
|
||||||
%% _X_Ys3 = [[{X,Y}, {A,B}, {C,D}] || X <- All_list, Y <- All_list, X /= Y,
|
_X_Ys3 = [[{X,Y}, {A,B}, {C,D}] || X <- All_list, Y <- All_list, X /= Y,
|
||||||
%% A <- All_list, B <- All_list, A /= B,
|
A <- All_list, B <- All_list, A /= B,
|
||||||
%% C <- All_list, D <- All_list, C /= D,
|
C <- All_list, D <- All_list, C /= D,
|
||||||
%% X /= A, X /= C, A /= C],
|
X /= A, X /= C, A /= C],
|
||||||
%% Concat = _X_Ys1,
|
%% Concat = _X_Ys1,
|
||||||
%% %% Concat = _X_Ys2,
|
%% Concat = _X_Ys2,
|
||||||
%% %% Concat = _X_Ys1 ++ _X_Ys2,
|
%% Concat = _X_Ys1 ++ _X_Ys2,
|
||||||
%% %% %% Concat = _X_Ys3,
|
%% %% Concat = _X_Ys3,
|
||||||
%% %% Concat = _X_Ys1 ++ _X_Ys2 ++ _X_Ys3,
|
Concat = _X_Ys1 ++ _X_Ys2 ++ _X_Ys3,
|
||||||
%% random_sort(lists:usort([lists:sort(L) || L <- Concat])).
|
random_sort(lists:usort([lists:sort(L) || L <- Concat])).
|
||||||
|
|
||||||
%% %% for len=5 and 2 witnesses
|
%% %% for len=5 and 2 witnesses
|
||||||
%% [
|
%% [
|
||||||
|
|
Loading…
Reference in a new issue