WIP: changes to annotation management
This commit is contained in:
parent
8a61a85ae0
commit
65cd18939c
2 changed files with 85 additions and 27 deletions
|
@ -61,7 +61,7 @@
|
||||||
name :: pv1_server(),
|
name :: pv1_server(),
|
||||||
flap_limit :: non_neg_integer(),
|
flap_limit :: non_neg_integer(),
|
||||||
proj :: projection(),
|
proj :: projection(),
|
||||||
proj_unanimous :: boolean(),
|
proj_unanimous :: 'false' | erlang:timestamp(),
|
||||||
%%
|
%%
|
||||||
timer :: 'undefined' | timer:tref(),
|
timer :: 'undefined' | timer:tref(),
|
||||||
ignore_timer :: boolean(),
|
ignore_timer :: boolean(),
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
flap_start=?NOT_FLAPPING_START
|
flap_start=?NOT_FLAPPING_START
|
||||||
:: {{'epk', integer()}, erlang:timestamp()},
|
:: {{'epk', integer()}, erlang:timestamp()},
|
||||||
flap_last_up=[] :: list(),
|
flap_last_up=[] :: list(),
|
||||||
flap_last_up_change=now() :: erlang:now(),
|
flap_last_up_change=now() :: erlang:timestamp(),
|
||||||
flap_counts_last=[] :: list(),
|
flap_counts_last=[] :: list(),
|
||||||
not_sanes :: orddict:orddict(),
|
not_sanes :: orddict:orddict(),
|
||||||
sane_transitions = 0 :: non_neg_integer(),
|
sane_transitions = 0 :: non_neg_integer(),
|
||||||
|
@ -553,6 +553,18 @@ read_latest_projection_call_only2(ProjectionType, All_queried_list, S) ->
|
||||||
FLU <- All_queried_list],
|
FLU <- All_queried_list],
|
||||||
{Rs, S2}.
|
{Rs, S2}.
|
||||||
|
|
||||||
|
read_projection_call_only2(ProjectionType, Epoch, All_queried_list, S) ->
|
||||||
|
{_UpNodes, Partitions, S2} = calc_up_nodes(S),
|
||||||
|
DoIt = fun(Pid) ->
|
||||||
|
case (?FLU_PC:read_projection(Pid, ProjectionType, Epoch, ?TO)) of
|
||||||
|
{ok, P} -> P;
|
||||||
|
Else -> Else
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
Rs = [(catch perhaps_call_t(S, Partitions, FLU, fun(Pid) -> DoIt(Pid) end)) ||
|
||||||
|
FLU <- All_queried_list],
|
||||||
|
{Rs, S2}.
|
||||||
|
|
||||||
cl_read_latest_projection(ProjectionType, S) ->
|
cl_read_latest_projection(ProjectionType, S) ->
|
||||||
AllHosed = [],
|
AllHosed = [],
|
||||||
cl_read_latest_projection(ProjectionType, AllHosed, S).
|
cl_read_latest_projection(ProjectionType, AllHosed, S).
|
||||||
|
@ -808,6 +820,11 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
P_none0 = make_none_projection(
|
P_none0 = make_none_projection(
|
||||||
MyName, AllMembers, OldWitness_list,
|
MyName, AllMembers, OldWitness_list,
|
||||||
MembersDict),
|
MembersDict),
|
||||||
|
Why = if NewUPI == [] ->
|
||||||
|
no_real_servers;
|
||||||
|
true ->
|
||||||
|
not_enough_witnesses
|
||||||
|
end,
|
||||||
P_none1 = P_none0#projection_v1{
|
P_none1 = P_none0#projection_v1{
|
||||||
epoch_number=OldEpochNum + 1,
|
epoch_number=OldEpochNum + 1,
|
||||||
dbg=[{none_projection,true},
|
dbg=[{none_projection,true},
|
||||||
|
@ -821,7 +838,7 @@ calc_projection2(LastProj, RelativeToServer, AllHosed, Dbg,
|
||||||
{tent_upi, TentativeUPI},
|
{tent_upi, TentativeUPI},
|
||||||
{new_upi, NewUPI},
|
{new_upi, NewUPI},
|
||||||
{up_witnesses, UpWitnesses},
|
{up_witnesses, UpWitnesses},
|
||||||
{not_enough_witnesses,true}]},
|
{why_none, Why}]},
|
||||||
machi_projection:update_checksum(P_none1)
|
machi_projection:update_checksum(P_none1)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
@ -1965,11 +1982,28 @@ react_to_env_C103(#projection_v1{epoch_number=_Epoch_newprop} = _P_newprop,
|
||||||
%% looping C100->C103->C100.
|
%% looping C100->C103->C100.
|
||||||
react_to_env_C100(P_none, P_none, clear_flapping_state(S)).
|
react_to_env_C100(P_none, P_none, clear_flapping_state(S)).
|
||||||
|
|
||||||
react_to_env_C110(P_latest, #ch_mgr{name=MyName} = S) ->
|
react_to_env_C110(P_latest, #ch_mgr{name=MyName, proj=P_current,
|
||||||
|
proj_unanimous=ProjUnanimous} = S) ->
|
||||||
?REACT(c110),
|
?REACT(c110),
|
||||||
?REACT({c110, ?LINE, [{latest_epoch,P_latest#projection_v1.epoch_number}]}),
|
?REACT({c110, ?LINE, [{latest_epoch,P_latest#projection_v1.epoch_number}]}),
|
||||||
Extra_todo = [{react,get(react)}],
|
Extra1 = case inner_projection_exists(P_current) andalso
|
||||||
P_latest2 = machi_projection:update_dbg2(P_latest, Extra_todo),
|
inner_projection_exists(P_latest) andalso
|
||||||
|
(machi_projection:get_epoch_id(
|
||||||
|
inner_projection_or_self(P_current)) ==
|
||||||
|
machi_projection:get_epoch_id(
|
||||||
|
inner_projection_or_self(P_latest)))
|
||||||
|
andalso ProjUnanimous /= false of
|
||||||
|
true ->
|
||||||
|
EpochID = machi_projection:get_epoch_id(
|
||||||
|
inner_projection_or_self(P_latest)),
|
||||||
|
UnanimousTime = ProjUnanimous,
|
||||||
|
A = make_annotation(EpochID, UnanimousTime),
|
||||||
|
[A];
|
||||||
|
false ->
|
||||||
|
[]
|
||||||
|
end,
|
||||||
|
Extra2 = [{react,get(react)}],
|
||||||
|
P_latest2 = machi_projection:update_dbg2(P_latest, Extra1 ++ Extra2),
|
||||||
|
|
||||||
MyNamePid = proxy_pid(MyName, S),
|
MyNamePid = proxy_pid(MyName, S),
|
||||||
Goo = P_latest2#projection_v1.epoch_number,
|
Goo = P_latest2#projection_v1.epoch_number,
|
||||||
|
@ -2034,6 +2068,7 @@ react_to_env_C120(P_latest, FinalProps, #ch_mgr{proj_history=H,
|
||||||
|
|
||||||
diversion_c120_verbose_goop(P_latest, S),
|
diversion_c120_verbose_goop(P_latest, S),
|
||||||
?REACT({c120, [{latest, machi_projection:make_summary(P_latest)}]}),
|
?REACT({c120, [{latest, machi_projection:make_summary(P_latest)}]}),
|
||||||
|
io:format(user, "C120: ~w wrote ~w ~W\n", [S#ch_mgr.name, P_latest#projection_v1.epoch_number, P_latest#projection_v1.epoch_csum, 6]),
|
||||||
{{now_using, FinalProps, P_latest#projection_v1.epoch_number},
|
{{now_using, FinalProps, P_latest#projection_v1.epoch_number},
|
||||||
set_proj(S#ch_mgr{proj_history=H2,
|
set_proj(S#ch_mgr{proj_history=H2,
|
||||||
sane_transitions=Xtns + 1}, P_latest)}.
|
sane_transitions=Xtns + 1}, P_latest)}.
|
||||||
|
@ -2606,7 +2641,7 @@ projection_transition_is_sane_except_si_epoch(
|
||||||
poll_private_proj_is_upi_unanimous(#ch_mgr{consistency_mode=ap_mode} = S) ->
|
poll_private_proj_is_upi_unanimous(#ch_mgr{consistency_mode=ap_mode} = S) ->
|
||||||
S;
|
S;
|
||||||
poll_private_proj_is_upi_unanimous(#ch_mgr{consistency_mode=cp_mode,
|
poll_private_proj_is_upi_unanimous(#ch_mgr{consistency_mode=cp_mode,
|
||||||
proj_unanimous=true} = S) ->
|
proj_unanimous={_,_,_}} = S) ->
|
||||||
S;
|
S;
|
||||||
poll_private_proj_is_upi_unanimous(#ch_mgr{consistency_mode=cp_mode,
|
poll_private_proj_is_upi_unanimous(#ch_mgr{consistency_mode=cp_mode,
|
||||||
proj_unanimous=false,
|
proj_unanimous=false,
|
||||||
|
@ -2624,17 +2659,17 @@ poll_private_proj_is_upi_unanimous_sleep(Count, S) when Count > 2 ->
|
||||||
poll_private_proj_is_upi_unanimous_sleep(Count, S) ->
|
poll_private_proj_is_upi_unanimous_sleep(Count, S) ->
|
||||||
timer:sleep((Count * Count) * 50),
|
timer:sleep((Count * Count) * 50),
|
||||||
case poll_private_proj_is_upi_unanimous3(S) of
|
case poll_private_proj_is_upi_unanimous3(S) of
|
||||||
#ch_mgr{proj_unanimous=true} = S2 ->
|
#ch_mgr{proj_unanimous=false} = S2 ->
|
||||||
S2;
|
poll_private_proj_is_upi_unanimous_sleep(Count + 1, S2);
|
||||||
S2 ->
|
S2 ->
|
||||||
poll_private_proj_is_upi_unanimous_sleep(Count + 1, S2)
|
S2
|
||||||
end.
|
end.
|
||||||
|
|
||||||
poll_private_proj_is_upi_unanimous3(#ch_mgr{name=_MyName, proj=Proj0,
|
poll_private_proj_is_upi_unanimous3(#ch_mgr{name=MyName, proj=P_current,
|
||||||
opts=MgrOpts} = S) ->
|
opts=MgrOpts} = S) ->
|
||||||
Proj = inner_projection_or_self(Proj0),
|
Proj_ios = inner_projection_or_self(P_current),
|
||||||
UPI = Proj#projection_v1.upi,
|
UPI = Proj_ios#projection_v1.upi,
|
||||||
EpochID = machi_projection:make_epoch_id(Proj),
|
EpochID = machi_projection:make_epoch_id(Proj_ios),
|
||||||
{Rs, S2} = read_latest_projection_call_only2(private, UPI, S),
|
{Rs, S2} = read_latest_projection_call_only2(private, UPI, S),
|
||||||
Rs2 = [if is_record(P, projection_v1) ->
|
Rs2 = [if is_record(P, projection_v1) ->
|
||||||
machi_projection:make_epoch_id(P);
|
machi_projection:make_epoch_id(P);
|
||||||
|
@ -2643,21 +2678,41 @@ poll_private_proj_is_upi_unanimous3(#ch_mgr{name=_MyName, proj=Proj0,
|
||||||
end || #projection_v1{}=P <- Rs],
|
end || #projection_v1{}=P <- Rs],
|
||||||
case lists:usort(Rs2) of
|
case lists:usort(Rs2) of
|
||||||
[EID] when EID == EpochID ->
|
[EID] when EID == EpochID ->
|
||||||
Annotation = {private_proj_is_upi_unanimous, {EpochID, now()}},
|
Now = os:timestamp(),
|
||||||
%% Careful, use the outer projection here!
|
Annotation = make_annotation(EpochID, Now),
|
||||||
NewDbg2 = [Annotation|Proj0#projection_v1.dbg2],
|
NewDbg2 = [Annotation|P_current#projection_v1.dbg2],
|
||||||
NewProj = Proj0#projection_v1{dbg2=NewDbg2},
|
NewProj = P_current#projection_v1{dbg2=NewDbg2},
|
||||||
ProjStore = get_projection_store_regname(MgrOpts),
|
ProjStore = case get_projection_store_regname(MgrOpts) of
|
||||||
|
undefined ->
|
||||||
|
machi_flu_psup:make_proj_supname(MyName);
|
||||||
|
PStr ->
|
||||||
|
PStr
|
||||||
|
end,
|
||||||
|
[io:format(user, "whereis(~w) ~w, ", [X, whereis(X)]) ||
|
||||||
|
X <- [a_pstore, a_pstore2]],
|
||||||
|
io:format(user, "POLL: ~w updates ~w ~W\n", [S#ch_mgr.name, NewProj#projection_v1.epoch_number, NewProj#projection_v1.epoch_csum, 6]),
|
||||||
ok = machi_projection_store:write(ProjStore, private, NewProj),
|
ok = machi_projection_store:write(ProjStore, private, NewProj),
|
||||||
%% Unwedge our FLU.
|
%% Unwedge our FLU.
|
||||||
io:format(user, "\nUnwedge ~w @ ~W\n", [_MyName, EpochID, 7]),
|
io:format(user, "\nUnwedge ~w @ ~W\n", [MyName, EpochID, 7]),
|
||||||
{ok, NotifyPid} = machi_projection_store:get_wedge_notify_pid(ProjStore),
|
{ok, NotifyPid} = machi_projection_store:get_wedge_notify_pid(ProjStore),
|
||||||
_ = machi_flu1:update_wedge_state(NotifyPid, false, EpochID),
|
_ = machi_flu1:update_wedge_state(NotifyPid, false, EpochID),
|
||||||
S2#ch_mgr{proj_unanimous=true};
|
S2#ch_mgr{proj_unanimous=Now};
|
||||||
_Else ->
|
_Else ->
|
||||||
|
io:format(user, "poll by ~w: want ~W got ~W\n", [MyName, EpochID, 6, _Else, 8]),
|
||||||
S2
|
S2
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
poll_read_private_projections(#projection_v1{inner=undefined,
|
||||||
|
epoch_number=Epoch,
|
||||||
|
upi=UPI}=_P_current, S) ->
|
||||||
|
read_projection_call_only2(private, Epoch, UPI, S);
|
||||||
|
poll_read_private_projections(#projection_v1{inner=_not_undefined,
|
||||||
|
upi=UPI}=_P_current, S) ->
|
||||||
|
%% For inner projections, we are (by definition) flapping, and the
|
||||||
|
%% outer epoch numbers are (by definition) unstable. However, any
|
||||||
|
%% observed use of the the inner proj epoch # is what we need.
|
||||||
|
read_latest_projection_call_only2(private, UPI, S).
|
||||||
|
|
||||||
sleep_ranked_order(MinSleep, MaxSleep, FLU, FLU_list) ->
|
sleep_ranked_order(MinSleep, MaxSleep, FLU, FLU_list) ->
|
||||||
USec = calc_sleep_ranked_order(MinSleep, MaxSleep, FLU, FLU_list),
|
USec = calc_sleep_ranked_order(MinSleep, MaxSleep, FLU, FLU_list),
|
||||||
timer:sleep(USec),
|
timer:sleep(USec),
|
||||||
|
@ -3104,8 +3159,7 @@ make_zerf2(OldEpochNum, Up, MajoritySize, MyName, AllMembers, OldWitness_list,
|
||||||
MembersDict, OldFlap, S) ->
|
MembersDict, OldFlap, S) ->
|
||||||
try
|
try
|
||||||
Proj = zerf_find_last_common(MajoritySize, Up, S),
|
Proj = zerf_find_last_common(MajoritySize, Up, S),
|
||||||
Proj2 =
|
Proj2 = Proj#projection_v1{flap=OldFlap, dbg2=[]}
|
||||||
Proj#projection_v1{flap=OldFlap}
|
|
||||||
, io:format(user, "ZERF ~w\n", [machi_projection:make_summary(Proj2)]),
|
, io:format(user, "ZERF ~w\n", [machi_projection:make_summary(Proj2)]),
|
||||||
Proj2
|
Proj2
|
||||||
catch
|
catch
|
||||||
|
@ -3140,7 +3194,8 @@ zerf_find_last_common(MajoritySize, Up, S) ->
|
||||||
[zerf_find_last_annotated(FLU,MajoritySize,S) || FLU <- Up]))) of
|
[zerf_find_last_annotated(FLU,MajoritySize,S) || FLU <- Up]))) of
|
||||||
[] ->
|
[] ->
|
||||||
throw({zerf,no_common});
|
throw({zerf,no_common});
|
||||||
[P|_] ->
|
[P|_]=_TheList ->
|
||||||
|
io:format(user, "Zerf results: ~P\n", [ [machi_projection:make_summary(X) || X <- _TheList], 20]),
|
||||||
%% TODO is this simple sort really good enough?
|
%% TODO is this simple sort really good enough?
|
||||||
P
|
P
|
||||||
end.
|
end.
|
||||||
|
@ -3149,7 +3204,7 @@ zerf_find_last_annotated(FLU, MajoritySize, S) ->
|
||||||
Proxy = proxy_pid(FLU, S),
|
Proxy = proxy_pid(FLU, S),
|
||||||
{ok, Epochs} = ?FLU_PC:list_all_projections(Proxy, private, 60*1000),
|
{ok, Epochs} = ?FLU_PC:list_all_projections(Proxy, private, 60*1000),
|
||||||
P = lists:foldl(
|
P = lists:foldl(
|
||||||
fun(Epoch, #projection_v1{}=Proj) ->
|
fun(_Epoch, #projection_v1{}=Proj) ->
|
||||||
Proj;
|
Proj;
|
||||||
(Epoch, Acc) ->
|
(Epoch, Acc) ->
|
||||||
{ok, Proj} = ?FLU_PC:read_projection(Proxy, private,
|
{ok, Proj} = ?FLU_PC:read_projection(Proxy, private,
|
||||||
|
@ -3174,7 +3229,7 @@ zerf_find_last_annotated(FLU, MajoritySize, S) ->
|
||||||
Acc
|
Acc
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end, first_accumulator, Epochs),
|
end, first_accumulator, lists:reverse(Epochs)),
|
||||||
if is_record(P, projection_v1) ->
|
if is_record(P, projection_v1) ->
|
||||||
P;
|
P;
|
||||||
true ->
|
true ->
|
||||||
|
@ -3303,3 +3358,6 @@ calc_consistency_mode(_Witness_list) ->
|
||||||
|
|
||||||
set_proj(S, Proj) ->
|
set_proj(S, Proj) ->
|
||||||
S#ch_mgr{proj=Proj, proj_unanimous=false}.
|
S#ch_mgr{proj=Proj, proj_unanimous=false}.
|
||||||
|
|
||||||
|
make_annotation(EpochID, Time) ->
|
||||||
|
{private_proj_is_upi_unanimous, {EpochID, Time}}.
|
||||||
|
|
|
@ -837,7 +837,7 @@ make_listener_regname(BaseName) ->
|
||||||
%% registers.
|
%% registers.
|
||||||
|
|
||||||
make_projection_server_regname(BaseName) ->
|
make_projection_server_regname(BaseName) ->
|
||||||
list_to_atom(atom_to_list(BaseName) ++ "_pstore2").
|
list_to_atom(atom_to_list(BaseName) ++ "_pstore").
|
||||||
|
|
||||||
%% @doc Encode `Offset + Size + TaggedCSum' into an `iolist()' type for
|
%% @doc Encode `Offset + Size + TaggedCSum' into an `iolist()' type for
|
||||||
%% internal storage by the FLU.
|
%% internal storage by the FLU.
|
||||||
|
|
Loading…
Reference in a new issue