Modify chain mostly works, better

This commit is contained in:
Scott Lystig Fritchie 2015-12-10 00:12:34 +09:00
parent b0a9e65ca2
commit 61ef7739cd
2 changed files with 19 additions and 46 deletions

View file

@ -82,8 +82,10 @@
mode :: pv1_consistency_mode(), mode :: pv1_consistency_mode(),
full :: [p_srvr()], full :: [p_srvr()],
witnesses :: [p_srvr()], witnesses :: [p_srvr()],
old_all :: [pv1_server()], old_all :: [pv1_server()], % guard against some races
old_witnesses :: [pv1_server()], old_witnesses :: [pv1_server()], % guard against some races
local_run :: [pv1_server()], % must be tailored to each machine!
local_stop :: [pv1_server()], % must be tailored to each machine!
props = [] :: list() % proplist for other related info props = [] :: list() % proplist for other related info
}). }).

View file

@ -378,9 +378,7 @@ bootstrap_chain2(#chain_def_v1{name=NewChainName, mode=NewCMode,
"mode=~w all=~w witnesses=~w\n", "mode=~w all=~w witnesses=~w\n",
[NewChainName, FLU, NewCMode, [NewChainName, FLU, NewCMode,
NewAll_list, NewWitnesses_list]), NewAll_list, NewWitnesses_list]),
AddedFLUs = NewAll_list -- OldAll_list, ok;
RemovedFLUs = OldAll_list -- NewAll_list,
{ok, AddedFLUs, RemovedFLUs};
chain_bad_state=Else -> chain_bad_state=Else ->
lager:error("Attempt to bootstrap chain ~w via FLU ~w " lager:error("Attempt to bootstrap chain ~w via FLU ~w "
"failed (no retries): ~w (defn ~w)\n", "failed (no retries): ~w (defn ~w)\n",
@ -499,50 +497,34 @@ process_pending_chains(P_Chains, S) ->
lists:foldl(fun process_pending_chain/2, S, P_Chains). lists:foldl(fun process_pending_chain/2, S, P_Chains).
process_pending_chain({File, CD}, S) -> process_pending_chain({File, CD}, S) ->
#chain_def_v1{name=Name, full=Full, witnesses=Witnesses} = CD, #chain_def_v1{name=Name,
local_stop=LocalStopFLUs, local_run=LocalRunFLUs} = CD,
case sanitize_chain_def_records([CD]) of case sanitize_chain_def_records([CD]) of
[CD] -> [CD] ->
RunningFLUs = get_local_running_flus(), case LocalRunFLUs of
AllNames = [FLUName || #p_srvr{name=FLUName} <- Full ++ Witnesses],
case ordsets:intersection(ordsets:from_list(AllNames),
ordsets:from_list(RunningFLUs)) of
[] -> [] ->
%% TODO: hahahah, /me cries ... so, there's a problem if case LocalStopFLUs of
%% we crash at the end of process_pending_chain2(), then
%% we don't delete the pending #chain_def_v1{} file ... so
%% we'll come to this same path the next time, and
%% get_current_chain_for_running_flus() may tell us that
%% there are zero FLUs running for this chain ... because
%% they were stopped before the crash. Silly.
%%
%% TODO: fix this gap by adding another field to
%% #chain_def_v1{} that specifies what *policy*
%% believes/states/defines/THE_TRUTH about which
%% FLUs in the chain are configured on this machine.
%% Then always use exactly that truth to guide us.
case get_current_chain_for_running_flus(CD, RunningFLUs) of
[] -> [] ->
lager:error("Pending chain config file ~s has no " lager:error("Pending chain config file ~s has no "
"FLUs on this machine, rejected\n", "FLUs on this machine, rejected\n",
[File]), [File]),
_ = move_to_rejected(File, S), _ = move_to_rejected(File, S),
S; S;
RemovedFLUs -> [_|_] ->
lager:info("Pending chain config file ~s creates " lager:info("Pending chain config file ~s stops "
"chain ~w of length 0, " "all local members of chain ~w: ~w\n",
"stopping FLUS: ~w\n", [File, Name, LocalStopFLUs]),
[File, Name, RemovedFLUs]), process_pending_chain2(File, CD, LocalStopFLUs,
process_pending_chain2(File, CD, RemovedFLUs,
delete, S) delete, S)
end; end;
[FLU|_] -> [FLU|_] ->
%% TODO: Between the successful chain change inside of %% TODO: Between the successful chain change inside of
%% bootstrap_chain() (and before it returns to us!) and %% bootstrap_chain() (and before it returns to us!) and
%% the return of process_pending_chain2(), we have a race %% the return of process_pending_chain2(), we have a race
%% window if this process crashes. %% window if this process crashes. (Review again!)
case bootstrap_chain(CD, FLU) of case bootstrap_chain(CD, FLU) of
{ok, _AddedFLUs, RemovedFLUs} -> ok ->
process_pending_chain2(File, CD, RemovedFLUs, process_pending_chain2(File, CD, LocalStopFLUs,
move, S); move, S);
Else -> Else ->
lager:error("Pending chain config file ~s " lager:error("Pending chain config file ~s "
@ -627,18 +609,7 @@ move_to_chain_config(Name, File, S) ->
S. S.
delete_chain_config(Name, File, S) -> delete_chain_config(Name, File, S) ->
lager:info("Deleting chain config file ~w for chain ~w\n", [File, Name]), lager:info("Deleting chain config file ~s for chain ~w\n", [File, Name]),
Dst = get_chain_config_dir(S), Dst = get_chain_config_dir(S),
ok = file:delete(Dst ++ "/" ++ atom_to_list(Name)), ok = file:delete(Dst ++ "/" ++ atom_to_list(Name)),
S. S.
get_current_chain_for_running_flus(#chain_def_v1{name=Name}, RunningFLUs) ->
FLU_CurChs = [begin
PStore = machi_flu1:make_projection_server_regname(FLU),
{ok, #projection_v1{chain_name=Ch}} =
machi_projection_store:read_latest_projection(
PStore, private),
{FLU, Ch}
end || FLU <- RunningFLUs],
[FLU || {FLU, CurChain} <- FLU_CurChs,
CurChain == Name].