WIP: egadz, a refactoring mess, but finally AP mode not sucky
This commit is contained in:
parent
a71e9543fe
commit
4e7d1f2310
1 changed files with 131 additions and 102 deletions
|
@ -65,7 +65,7 @@
|
|||
timer :: 'undefined' | timer:tref(),
|
||||
ignore_timer :: boolean(),
|
||||
proj_history :: queue:queue(),
|
||||
flap_count=0 :: integer(),
|
||||
flap_count=0 :: non_neg_integer(), % I am flapping if > 0.
|
||||
flap_start=?NOT_FLAPPING_START
|
||||
:: {{'epk', integer()}, erlang:timestamp()},
|
||||
flap_last_up=[] :: list(),
|
||||
|
@ -1120,6 +1120,7 @@ react_to_env_A30(Retries, P_latest, LatestUnanimousP, _ReadExtra,
|
|||
#ch_mgr{name=MyName, proj=P_current,
|
||||
consistency_mode=CMode, flap_limit=FlapLimit} = S) ->
|
||||
?REACT(a30),
|
||||
case length(get(react)) of XX when XX > 500 -> io:format(user, "A30! ~w: ~P\n", [MyName, get(react), 140]), timer:sleep(500); _ -> ok end,
|
||||
{P_newprop1, S2, Up} = calc_projection(S, MyName),
|
||||
?REACT({a30, ?LINE, [{current, machi_projection:make_summary(S#ch_mgr.proj)}]}),
|
||||
?REACT({a30, ?LINE, [{newprop1, machi_projection:make_summary(P_newprop1)}]}),
|
||||
|
@ -1160,6 +1161,7 @@ react_to_env_A30(Retries, P_latest, LatestUnanimousP, _ReadExtra,
|
|||
{flap_limit, FlapLimit}]}),
|
||||
{P_newprop3, S3}
|
||||
end,
|
||||
?REACT({a30, ?LINE, [{newprop10, machi_projection:make_summary(P_newprop10)}]}),
|
||||
|
||||
%% Here's a more common reason for moving from inner projection to
|
||||
%% a normal projection: the old proj has an inner but the newprop
|
||||
|
@ -1267,72 +1269,97 @@ react_to_env_A30(Retries, P_latest, LatestUnanimousP, _ReadExtra,
|
|||
a30_make_inner_projection(P_current, P_newprop3, P_latest, Up,
|
||||
#ch_mgr{name=MyName, consistency_mode=CMode} = S) ->
|
||||
AllHosed = get_all_hosed(P_newprop3),
|
||||
P_current_inner = inner_projection_or_self(P_current),
|
||||
{P_i, S_i, _Up} = calc_projection2(P_current_inner,
|
||||
MyName, AllHosed, [], S),
|
||||
P_current_has_inner_p = inner_projection_exists(P_current),
|
||||
P_current_ios = inner_projection_or_self(P_current),
|
||||
NewEpochOuter = erlang:max(P_latest#projection_v1.epoch_number + 1,
|
||||
P_newprop3#projection_v1.epoch_number),
|
||||
{P_i1, S_i, _Up} = calc_projection2(P_current_ios,
|
||||
MyName, AllHosed, [], S),
|
||||
?REACT({a30, ?LINE, [{raw_all_hosed,get_all_hosed(P_newprop3)},
|
||||
{up, Up},
|
||||
{all_hosed, AllHosed},
|
||||
{p_c_i, machi_projection:make_summary(P_current_inner)},
|
||||
{p_i,machi_projection:make_summary(P_i)}]}),
|
||||
{p_c_i, machi_projection:make_summary(P_current_ios)},
|
||||
{p_i1, machi_projection:make_summary(P_i1)}]}),
|
||||
%% The inner projection will have a fake author, which
|
||||
%% everyone will agree is the largest UPI member's
|
||||
%% name.
|
||||
BiggestUPIMember =
|
||||
if P_i#projection_v1.upi == [] ->
|
||||
if P_i1#projection_v1.upi == [] ->
|
||||
%% Oops, ok, fall back to author
|
||||
P_i#projection_v1.author_server;
|
||||
P_i1#projection_v1.author_server;
|
||||
true ->
|
||||
lists:last(lists:sort(P_i#projection_v1.upi))
|
||||
lists:last(lists:sort(P_i1#projection_v1.upi))
|
||||
end,
|
||||
P_i2 = P_i#projection_v1{author_server=BiggestUPIMember},
|
||||
P_inner = case lists:member(MyName, AllHosed)
|
||||
andalso
|
||||
CMode == ap_mode
|
||||
of
|
||||
false ->
|
||||
P_i2;
|
||||
true ->
|
||||
P_i2#projection_v1{
|
||||
upi=[MyName],
|
||||
repairing=[],
|
||||
down=P_i2#projection_v1.all_members
|
||||
-- [MyName]}
|
||||
end,
|
||||
P_i2 = P_i1#projection_v1{author_server=BiggestUPIMember},
|
||||
P_i3 = case lists:member(MyName, AllHosed)
|
||||
andalso
|
||||
CMode == ap_mode
|
||||
of
|
||||
false ->
|
||||
P_i2;
|
||||
true ->
|
||||
%% Fall back to a safe AP mode chain: just me.
|
||||
P_i2#projection_v1{
|
||||
upi=[MyName],
|
||||
repairing=[],
|
||||
down=P_i2#projection_v1.all_members
|
||||
-- [MyName]}
|
||||
end,
|
||||
#projection_v1{epoch_number=Epoch_p_inner,
|
||||
upi=UPI_p_inner,
|
||||
repairing=Repairing_p_inner} = P_inner,
|
||||
LatestHasCompatibleInner =
|
||||
repairing=Repairing_p_inner} = P_i3,
|
||||
HasCompatibleInner =
|
||||
case inner_projection_exists(P_latest) of
|
||||
true ->
|
||||
P_latest_i = inner_projection_or_self(P_latest),
|
||||
#projection_v1{epoch_number=___Epoch_current_x,
|
||||
upi=UPI_current_x,
|
||||
repairing=Repairing_current_x} = P_current_ios,
|
||||
#projection_v1{epoch_number=Epoch_latest_i,
|
||||
upi=UPI_latest_i,
|
||||
repairing=Repairing_latest_i} = P_latest_i,
|
||||
?REACT({a30, ?LINE, [{epoch_latest_i, Epoch_latest_i},
|
||||
{upi_latest_i, UPI_latest_i},
|
||||
{repairing_latest_i}]}),
|
||||
%io:format(user, "INNER: ~p line ~p ~p\n", [{epoch_latest_i, Epoch_latest_i}, {epoch_final_inner, FinalInnerEpoch}, {upi_latest_i, UPI_latest_i}, {repairing_latest_i}]),
|
||||
if %% TODO yo delete? Epoch_latest_i > FinalInnerEpoch
|
||||
%% TODO yo delete? andalso
|
||||
UPI_p_inner == UPI_latest_i
|
||||
SameEnough_p =
|
||||
UPI_latest_i == P_current_ios#projection_v1.upi
|
||||
andalso
|
||||
Repairing_p_inner == Repairing_latest_i ->
|
||||
%% Use latest's inner projection instead!
|
||||
Repairing_latest_i == P_current_ios#projection_v1.repairing
|
||||
andalso
|
||||
Epoch_latest_i >= P_current_ios#projection_v1.epoch_number,
|
||||
CurrentInner_and_Disjoint_p =
|
||||
P_current_has_inner_p
|
||||
andalso
|
||||
ordsets:is_disjoint(
|
||||
ordsets:from_list(UPI_current_x ++ Repairing_current_x),
|
||||
ordsets:from_list(UPI_latest_i ++ Repairing_latest_i)),
|
||||
if SameEnough_p ->
|
||||
?REACT({a30, ?LINE, []}),
|
||||
%io:format(user, "INNER: ~p line ~p\n", [MyName, ?LINE]),
|
||||
machi_projection:update_checksum(
|
||||
P_inner#projection_v1{inner=P_latest_i});
|
||||
P_latest_i;
|
||||
CurrentInner_and_Disjoint_p ->
|
||||
?REACT({a30, ?LINE, []}),
|
||||
P_current_ios;
|
||||
true ->
|
||||
?REACT({a30, ?LINE, []}),
|
||||
false
|
||||
end;
|
||||
false ->
|
||||
?REACT({a30, ?LINE, []}),
|
||||
false
|
||||
#projection_v1{upi=UPI_i3,
|
||||
repairing=Repairing_i3} = P_i3,
|
||||
if P_current_has_inner_p,
|
||||
UPI_i3 == P_current_ios#projection_v1.upi,
|
||||
Repairing_i3 == P_current_ios#projection_v1.repairing ->
|
||||
?REACT({a30, ?LINE, []}),
|
||||
P_current_ios;
|
||||
true ->
|
||||
?REACT({a30, ?LINE, []}),
|
||||
false
|
||||
end
|
||||
end,
|
||||
if LatestHasCompatibleInner /= false ->
|
||||
{LatestHasCompatibleInner, S_i};
|
||||
if HasCompatibleInner /= false ->
|
||||
P_newprop4 = machi_projection:update_checksum(
|
||||
P_newprop3#projection_v1{inner=HasCompatibleInner}),
|
||||
{P_newprop4, S_i};
|
||||
true ->
|
||||
FinalInnerEpoch =
|
||||
case inner_projection_exists(P_current) of
|
||||
|
@ -1340,49 +1367,25 @@ a30_make_inner_projection(P_current, P_newprop3, P_latest, Up,
|
|||
?REACT({a30xyzxyz, ?LINE, [P_newprop3#projection_v1.epoch_number]}),
|
||||
FinalCreation = P_newprop3#projection_v1.creation_time,
|
||||
P_newprop3#projection_v1.epoch_number;
|
||||
%% AllFlapCounts_epk =
|
||||
%% [Epk || {{Epk,_FlTime}, _FlCount} <-
|
||||
%% get_all_flap_counts(P_newprop3)],
|
||||
%% case AllFlapCounts_epk of
|
||||
%% [] ->
|
||||
%% ?REACT({a30xyzxyz, ?LINE, [P_newprop3#projection_v1.epoch_number]}),
|
||||
%% P_newprop3#projection_v1.epoch_number;
|
||||
%% [_|_] ->
|
||||
%% ?REACT({a30xyzxyz, ?LINE, [AllFlapCounts_epk]}),
|
||||
%% lists:max(AllFlapCounts_epk)
|
||||
%% end;
|
||||
true ->
|
||||
P_oldinner = inner_projection_or_self(P_current),
|
||||
if P_oldinner#projection_v1.upi ==
|
||||
P_inner#projection_v1.upi
|
||||
andalso
|
||||
P_oldinner#projection_v1.repairing ==
|
||||
P_inner#projection_v1.repairing
|
||||
andalso
|
||||
P_oldinner#projection_v1.down ==
|
||||
P_inner#projection_v1.down ->
|
||||
?REACT({a30xyzxyz, ?LINE, [P_oldinner#projection_v1.epoch_number]}),
|
||||
FinalCreation = P_oldinner#projection_v1.creation_time,
|
||||
P_oldinner#projection_v1.epoch_number;
|
||||
true ->
|
||||
?REACT({a30xyzxyz, ?LINE, [P_oldinner#projection_v1.epoch_number + 1]}),
|
||||
FinalCreation = P_newprop3#projection_v1.creation_time,
|
||||
P_oldinner#projection_v1.epoch_number + 1
|
||||
end
|
||||
?REACT({a30xyzxyz, ?LINE, [P_oldinner#projection_v1.epoch_number + 1]}),
|
||||
FinalCreation = P_newprop3#projection_v1.creation_time,
|
||||
P_oldinner#projection_v1.epoch_number + 1
|
||||
end,
|
||||
%% TODO: When we implement the real chain repair function, we
|
||||
%% need to keep in mind that an inner projection with
|
||||
%% up nodes > 1, repair is required there! In the
|
||||
%% current simulator, repair is not simulated and
|
||||
%% finished (and then growing the UPI list). Fix.
|
||||
P_inner2 = machi_projection:update_checksum(
|
||||
P_inner#projection_v1{epoch_number=FinalInnerEpoch,
|
||||
creation_time=FinalCreation}),
|
||||
P_i4 = machi_projection:update_checksum(
|
||||
P_i3#projection_v1{epoch_number=FinalInnerEpoch,
|
||||
creation_time=FinalCreation}),
|
||||
?REACT({a30, ?LINE, [{inner_summary,
|
||||
machi_projection:make_summary(P_inner2)}]}),
|
||||
machi_projection:make_summary(P_i4)}]}),
|
||||
%% Put it all together.
|
||||
P_newprop4 = machi_projection:update_checksum(
|
||||
P_newprop3#projection_v1{inner=P_inner2}),
|
||||
P_newprop3#projection_v1{inner=P_i4}),
|
||||
{P_newprop4, S_i}
|
||||
end.
|
||||
|
||||
|
@ -1410,7 +1413,9 @@ react_to_env_A40(Retries, P_newprop, P_latest, LatestUnanimousP,
|
|||
P_latest#projection_v1.author_server /= MyName,
|
||||
?REACT({a40, ?LINE,
|
||||
[{latest_author, P_latest#projection_v1.author_server},
|
||||
{author_is_down_p, LatestAuthorDownP}]}),
|
||||
{author_is_down_p, LatestAuthorDownP},
|
||||
{latest_flap, P_latest#projection_v1.flap},
|
||||
{newprop_flap, P_newprop#projection_v1.flap}]}),
|
||||
|
||||
if
|
||||
%% Epoch == 0 is reserved for first-time, just booting conditions.
|
||||
|
@ -1542,7 +1547,10 @@ react_to_env_B10(Retries, P_newprop, P_latest, LatestUnanimousP,
|
|||
#ch_mgr{name=MyName, flap_limit=FlapLimit, proj=P_current}=S)->
|
||||
?REACT(b10),
|
||||
|
||||
{_P_newprop_flap_time, P_newprop_flap_count} = get_flap_count(P_newprop),
|
||||
{P_newprop_flap_time, P_newprop_flap_count} = get_flap_count(P_newprop),
|
||||
?REACT({b10, ?LINE, [{newprop_epoch, P_newprop#projection_v1.epoch_number},
|
||||
{newprop_flap_time, P_newprop_flap_time},
|
||||
{newprop_flap_count, P_newprop_flap_count}]}),
|
||||
UnanimousLatestInnerNotRelevant_p =
|
||||
case inner_projection_exists(P_latest) of
|
||||
true when P_latest#projection_v1.author_server /= MyName ->
|
||||
|
@ -2011,16 +2019,16 @@ calculate_flaps(P_newprop, P_latest, _P_current, CurrentUp, _FlapLimit,
|
|||
?REACT({calculate_flaps, ?LINE, [{queue_len, queue:len(H)},
|
||||
{uniques, UniqueProposalSummaries}]}),
|
||||
P_latest_Flap = get_raw_flapping_i(P_latest),
|
||||
AmFlapping_or_StartingFlapping_p =
|
||||
AmFlappingNow_p = not (FlapStart == ?NOT_FLAPPING_START orelse
|
||||
FlapStart == undefined),
|
||||
StartFlapping_p =
|
||||
case {queue:len(H), UniqueProposalSummaries} of
|
||||
_ when not (FlapStart == ?NOT_FLAPPING_START orelse
|
||||
FlapStart == undefined) ->
|
||||
%% ?REACT({calculate_flaps,?LINE,[{am_flapping,stay_flapping}]}),
|
||||
_ when AmFlappingNow_p ->
|
||||
?REACT({calculate_flaps,?LINE,[{flap_start,FlapStart}]}),
|
||||
true;
|
||||
%% I'm already flapping, therefore don't start again.
|
||||
false;
|
||||
{N, _} when N >= 3,
|
||||
P_latest_Flap#flap_i.flap_count /= ?NOT_FLAPPING_START ->
|
||||
%%io:format(user, "CALC_FLAP: ~w: ~w\n", [MyName, machi_projection:make_summary(P_latest)]),
|
||||
P_latest_Flap#flap_i.flap_count /= ?NOT_FLAPPING_START->
|
||||
?REACT({calculate_flaps,?LINE,[{manifesto_clause,2}]}),
|
||||
true;
|
||||
{N, [_]} when N >= 3 ->
|
||||
|
@ -2031,42 +2039,66 @@ calculate_flaps(P_newprop, P_latest, _P_current, CurrentUp, _FlapLimit,
|
|||
false
|
||||
end,
|
||||
LeaveFlapping_p =
|
||||
if FlapLastUp /= [], CurrentUp /= FlapLastUp ->
|
||||
if
|
||||
StartFlapping_p ->
|
||||
%% If we're starting flapping on this iteration, don't ignore
|
||||
%% that intent.
|
||||
false;
|
||||
AmFlappingNow_p andalso
|
||||
FlapLastUp /= [] andalso CurrentUp /= FlapLastUp ->
|
||||
?REACT({calculate_flaps,?LINE,[{manifesto_clause,1}]}),
|
||||
true;
|
||||
true ->
|
||||
AmFlappingNow_p ->
|
||||
P_latest_LastStartTime =
|
||||
search_flap_counts(P_latest#projection_v1.author_server,
|
||||
FlapCountsLast),
|
||||
search_last_flap_counts(
|
||||
P_latest#projection_v1.author_server, FlapCountsLast),
|
||||
case get_flap_count(P_latest) of
|
||||
{?NOT_FLAPPING_START, _Count}
|
||||
when P_latest_LastStartTime == undefined ->
|
||||
%% latest proj not flapping & not flapping last time
|
||||
?REACT({calculate_flaps,?LINE,[]}),
|
||||
false;
|
||||
{Time, _Count} when Time == P_latest_LastStartTime ->
|
||||
{Curtime, _Count} when Curtime == P_latest_LastStartTime ->
|
||||
%% latest proj flapping & flapping last time
|
||||
?REACT({calculate_flaps,?LINE,[]}),
|
||||
false;
|
||||
{Time, _Count} when Time > P_latest_LastStartTime,
|
||||
P_latest_LastStartTime /= undefined ->
|
||||
{Curtime, _Count} when Curtime > P_latest_LastStartTime,
|
||||
P_latest_LastStartTime /= undefined,
|
||||
P_latest_LastStartTime /= ?NOT_FLAPPING_START ->
|
||||
%% latest proj flapping & older flapping last time:
|
||||
%% we didn't see this author flip out of its older
|
||||
%% flapping state. So we will leave flapping and then,
|
||||
%% if necessary, re-flap sometime later.
|
||||
?REACT({calculate_flaps,?LINE,
|
||||
[{manifesto_clause,3},
|
||||
{p_latest, machi_projection:make_summary(P_latest)},
|
||||
{time, Time},
|
||||
{curtime, Curtime},
|
||||
{flap_counts_last, FlapCountsLast},
|
||||
{laststart_time, P_latest_LastStartTime}]}),
|
||||
true;
|
||||
{0, 0} when P_latest_LastStartTime /= undefined ->
|
||||
?REACT({calculate_flaps,?LINE,[{manifesto_clause,2}]}),
|
||||
{0=Curtime, 0} when P_latest_LastStartTime /= undefined,
|
||||
P_latest_LastStartTime /= ?NOT_FLAPPING_START ->
|
||||
|
||||
?REACT({calculate_flaps,?LINE,
|
||||
[{manifesto_clause,2},
|
||||
{p_latest, machi_projection:make_summary(P_latest)},
|
||||
{curtime, Curtime},
|
||||
{flap_counts_last, FlapCountsLast},
|
||||
{laststart_time, P_latest_LastStartTime}]}),
|
||||
%% latest proj not flapping & flapping last time:
|
||||
%% this author
|
||||
true;
|
||||
_ ->
|
||||
?REACT({calculate_flaps,?LINE,[]}),
|
||||
false
|
||||
end
|
||||
end;
|
||||
true ->
|
||||
?REACT({calculate_flaps,?LINE,[]}),
|
||||
false
|
||||
end,
|
||||
%%io:format(user, "CALC_FLAP: ~w: am_or_start ~w leave ~w: ~p\n", [MyName, AmFlapping_or_StartingFlapping_p, LeaveFlapping_p, [X || X={calculate_flaps,_,_} <- get(react)]]),
|
||||
%%io:format(user, "CALC_FLAP: ~w: am_or_start ~w leave ~w\n", [MyName, AmFlapping_or_StartingFlapping_p, LeaveFlapping_p]),
|
||||
if LeaveFlapping_p -> io:format(user, "CALC_FLAP: ~w: am_or_start ~w leave ~w: ~p\n", [MyName, AmFlapping_or_StartingFlapping_p, LeaveFlapping_p, [X || X={calculate_flaps,_,_} <- lists:sublist(get(react), 3)]]); true -> ok end,
|
||||
if LeaveFlapping_p -> io:format(user, "CALC_FLAP: ~w: flapping_now ~w start ~w leave ~w: ~p\n", [MyName, AmFlappingNow_p, StartFlapping_p, LeaveFlapping_p, [X || X={calculate_flaps,_,_} <- lists:sublist(get(react), 3)]]); true -> ok end,
|
||||
AmFlapping_p = if LeaveFlapping_p -> false;
|
||||
true -> AmFlapping_or_StartingFlapping_p
|
||||
true -> AmFlappingNow_p orelse StartFlapping_p
|
||||
end,
|
||||
|
||||
if AmFlapping_p ->
|
||||
|
@ -2094,8 +2126,10 @@ if LeaveFlapping_p -> io:format(user, "CALC_FLAP: ~w: am_or_start ~w leave ~w: ~
|
|||
AllHosed = []
|
||||
end,
|
||||
|
||||
AllFlapCounts_with_my_new =
|
||||
[{MyName, NewFlapStart}|lists:keydelete(MyName, 1, AllFlapCounts)],
|
||||
FlappingI = make_flapping_i(NewFlapStart, NewFlapCount, AllHosed,
|
||||
AllFlapCounts, BadFLUs),
|
||||
AllFlapCounts_with_my_new, BadFLUs),
|
||||
%% NOTE: Just because we increment flaps here, there's no correlation
|
||||
%% to successful public proj store writes! For example,
|
||||
%% if we loop through states C2xx a few times, we would incr
|
||||
|
@ -3022,10 +3056,5 @@ calc_magic_down([H|T], G) ->
|
|||
[H|calc_magic_down(T, G)]
|
||||
end.
|
||||
|
||||
search_flap_counts(_FLU, []) ->
|
||||
undefined;
|
||||
search_flap_counts(FLU, [{FLU, {EpkTime, _Count}}|_]) ->
|
||||
EpkTime;
|
||||
search_flap_counts(FLU, [_|Tail]) ->
|
||||
search_flap_counts(FLU, Tail).
|
||||
|
||||
search_last_flap_counts(FLU, FlapCountsLast) ->
|
||||
proplists:get_value(FLU, FlapCountsLast, undefined).
|
||||
|
|
Loading…
Reference in a new issue