Bugfix (part II) rare race between just-finished repair and flapping ending
The prior commit wasn't sufficient: the range of transitions is wider than assumed by that commit. So, we take one of two options, with a TODO task of researching the other option.
This commit is contained in:
parent
96ca7b7082
commit
0f3d11e1bf
1 changed files with 34 additions and 7 deletions
|
@ -1417,21 +1417,48 @@ react_to_env_C100(P_newprop, P_latest,
|
||||||
?REACT({c100, ?LINE, [sane]}),
|
?REACT({c100, ?LINE, [sane]}),
|
||||||
erase(perhaps_reset_loop),
|
erase(perhaps_reset_loop),
|
||||||
react_to_env_C110(P_latest, S);
|
react_to_env_C110(P_latest, S);
|
||||||
_AnyOtherReturnValue ->
|
{expected_author2,_ExpectedAuthor2}=_ExpectedErr ->
|
||||||
case get(perhaps_reset_loop) of
|
case get(perhaps_reset_loop) of
|
||||||
undefined ->
|
undefined ->
|
||||||
put(perhaps_reset_loop, 1);
|
put(perhaps_reset_loop, 1),
|
||||||
|
?REACT({c100, ?LINE, [not_sane, get(why2), _ExpectedErr]}),
|
||||||
|
react_to_env_C300(P_newprop, P_latest, S);
|
||||||
X when X > 15 ->
|
X when X > 15 ->
|
||||||
Msg = lists:flatten(
|
%% Ha, yes, this is possible. For example:
|
||||||
io_lib:format("~P", [get(react), 300])),
|
%% outer: author=e,upi=[b,a,d],repair=[c,e]
|
||||||
exit({not_supposed_to_happen, ?MODULE, ?LINE, Msg});
|
%% inner: author=e,upi=[b,e], repair=[]
|
||||||
|
%% In this case, the transition from inner to outer by A30
|
||||||
|
%% has chosen the wrong author. We have two choices.
|
||||||
|
%% 1. Accept this transition, because it really was the
|
||||||
|
%% safe & transition-approved UPI+repeairing that we
|
||||||
|
%% were using while we were flapping. I'm 99% certain
|
||||||
|
%% that this is safe. TODO: Verify
|
||||||
|
%% 2. I'm not yet 100% certain that #1 is safe, so instead
|
||||||
|
%% we fall back to the one thing that we know is safe:
|
||||||
|
%% the 'none' projection, which lets the chain rebuild
|
||||||
|
%% itself normally during future iterations.
|
||||||
|
#projection_v1{epoch_number=Epoch_latest,
|
||||||
|
all_members=All_list,
|
||||||
|
members_dict=MembersDict} = P_latest,
|
||||||
|
P_none0 = make_none_projection(MyName, All_list, MembersDict),
|
||||||
|
P_none1 = P_none0#projection_v1{epoch_number=Epoch_latest},
|
||||||
|
Dbg = [{none_projection,true}],
|
||||||
|
P_none = machi_projection:update_checksum(
|
||||||
|
P_none1#projection_v1{dbg=Dbg}),
|
||||||
|
io:format(user, "YO: looping transition forced to none!\nNewProp: ~w\nLatest: ~w\nNone: ~w\n", [machi_projection:make_summary(P_newprop), machi_projection:make_summary(P_latest), machi_projection:make_summary(P_none)]),
|
||||||
|
%% Recurse to self!
|
||||||
|
react_to_env_C100(P_none, P_none, S);
|
||||||
X ->
|
X ->
|
||||||
put(perhaps_reset_loop, X+1)
|
put(perhaps_reset_loop, X+1),
|
||||||
end,
|
?REACT({c100, ?LINE, [not_sane, get(why2), _ExpectedErr]}),
|
||||||
|
react_to_env_C300(P_newprop, P_latest, S)
|
||||||
|
end;
|
||||||
|
_AnyOtherReturnValue ->
|
||||||
%% P_latest is not sane.
|
%% P_latest is not sane.
|
||||||
%% By process of elimination, P_newprop is best,
|
%% By process of elimination, P_newprop is best,
|
||||||
%% so let's write it.
|
%% so let's write it.
|
||||||
?REACT({c100, ?LINE, [not_sane, get(why2), _AnyOtherReturnValue]}),
|
?REACT({c100, ?LINE, [not_sane, get(why2), _AnyOtherReturnValue]}),
|
||||||
|
erase(perhaps_reset_loop),
|
||||||
react_to_env_C300(P_newprop, P_latest, S)
|
react_to_env_C300(P_newprop, P_latest, S)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue