WIP: intermediate refactoring
This commit is contained in:
parent
0a4c0f963e
commit
83f49472db
2 changed files with 58 additions and 38 deletions
|
@ -267,56 +267,73 @@ do_proj_write(private=ProjType, #projection_v1{epoch_number=Epoch}=Proj, S) ->
|
||||||
case S#state.max_public_epochid of
|
case S#state.max_public_epochid of
|
||||||
{PublicEpoch, _} when PublicEpoch =< Epoch ->
|
{PublicEpoch, _} when PublicEpoch =< Epoch ->
|
||||||
do_proj_write2(ProjType, Proj, S);
|
do_proj_write2(ProjType, Proj, S);
|
||||||
{PublicEpoch, _} ->
|
{_PublicEpoch, _} ->
|
||||||
{{error, bad_arg}, S}
|
{{error, bad_arg}, S}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_proj_write2(ProjType, #projection_v1{epoch_number=Epoch}=Proj, S) ->
|
do_proj_write2(ProjType, #projection_v1{epoch_csum=CSum}=Proj, S) ->
|
||||||
|
case (machi_projection:update_checksum(Proj))#projection_v1.epoch_csum of
|
||||||
|
CSum2 when CSum2 == CSum ->
|
||||||
|
do_proj_write3(ProjType, Proj, S);
|
||||||
|
_Else ->
|
||||||
|
io:format(user, "Oops ~s epoch ~w csum ~W expected ~W\n", [S#state.public_dir, Proj#projection_v1.epoch_number, _Else, 6, CSum, 6]),
|
||||||
|
{{error, bad_arg}, S}
|
||||||
|
end.
|
||||||
|
|
||||||
|
do_proj_write3(ProjType, #projection_v1{epoch_number=Epoch,
|
||||||
|
epoch_csum=CSum}=Proj, S) ->
|
||||||
%% TODO: We probably ought to check the projection checksum for sanity, eh?
|
%% TODO: We probably ought to check the projection checksum for sanity, eh?
|
||||||
Dir = pick_path(ProjType, S),
|
Dir = pick_path(ProjType, S),
|
||||||
Path = filename:join(Dir, epoch2name(Epoch)),
|
Path = filename:join(Dir, epoch2name(Epoch)),
|
||||||
case file:read_file_info(Path) of
|
case file:read_file(Path) of
|
||||||
{ok, _FI} ->
|
{ok, _Bin} when ProjType == public ->
|
||||||
|
{{error, written}, S};
|
||||||
|
{ok, Bin} when ProjType == private ->
|
||||||
|
#projection_v1{epoch_number=CurEpoch,
|
||||||
|
epoch_csum=CurCSum} = _CurProj = binary_to_term(Bin),
|
||||||
{{error, written}, S};
|
{{error, written}, S};
|
||||||
{error, enoent} ->
|
{error, enoent} ->
|
||||||
{ok, FH} = file:open(Path, [write, raw, binary]),
|
do_proj_write4(ProjType, Proj, Path, Epoch, S);
|
||||||
ok = file:write(FH, term_to_binary(Proj)),
|
|
||||||
ok = file:sync(FH),
|
|
||||||
ok = file:close(FH),
|
|
||||||
EffectiveProj = machi_chain_manager1:inner_projection_or_self(Proj),
|
|
||||||
EffectiveEpoch = EffectiveProj#projection_v1.epoch_number,
|
|
||||||
EpochId = {Epoch, Proj#projection_v1.epoch_csum},
|
|
||||||
EffectiveEpochId = {EffectiveEpoch, EffectiveProj#projection_v1.epoch_csum},
|
|
||||||
%%
|
|
||||||
NewS = if ProjType == public,
|
|
||||||
Epoch > element(1, S#state.max_public_epochid) ->
|
|
||||||
if Epoch == EffectiveEpoch ->
|
|
||||||
%% This is a regular projection, i.e.,
|
|
||||||
%% does not have an inner proj.
|
|
||||||
update_wedge_state(
|
|
||||||
S#state.wedge_notify_pid, true,
|
|
||||||
EffectiveEpochId);
|
|
||||||
Epoch /= EffectiveEpoch ->
|
|
||||||
%% This projection has an inner proj.
|
|
||||||
%% The outer proj is flapping, so we do
|
|
||||||
%% not bother wedging.
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
S#state{max_public_epochid=EpochId};
|
|
||||||
ProjType == private,
|
|
||||||
Epoch > element(1, S#state.max_private_epochid) ->
|
|
||||||
update_wedge_state(
|
|
||||||
S#state.wedge_notify_pid, false,
|
|
||||||
EffectiveEpochId),
|
|
||||||
S#state{max_private_epochid=EpochId};
|
|
||||||
true ->
|
|
||||||
S
|
|
||||||
end,
|
|
||||||
{ok, NewS};
|
|
||||||
{error, Else} ->
|
{error, Else} ->
|
||||||
{{error, Else}, S}
|
{{error, Else}, S}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
do_proj_write4(ProjType, Proj, Path, Epoch, S) ->
|
||||||
|
{ok, FH} = file:open(Path, [write, raw, binary]),
|
||||||
|
ok = file:write(FH, term_to_binary(Proj)),
|
||||||
|
ok = file:sync(FH),
|
||||||
|
ok = file:close(FH),
|
||||||
|
EffectiveProj = machi_chain_manager1:inner_projection_or_self(Proj),
|
||||||
|
EffectiveEpoch = EffectiveProj#projection_v1.epoch_number,
|
||||||
|
EpochId = {Epoch, Proj#projection_v1.epoch_csum},
|
||||||
|
EffectiveEpochId = {EffectiveEpoch, EffectiveProj#projection_v1.epoch_csum},
|
||||||
|
%%
|
||||||
|
NewS = if ProjType == public,
|
||||||
|
Epoch > element(1, S#state.max_public_epochid) ->
|
||||||
|
if Epoch == EffectiveEpoch ->
|
||||||
|
%% This is a regular projection, i.e.,
|
||||||
|
%% does not have an inner proj.
|
||||||
|
update_wedge_state(
|
||||||
|
S#state.wedge_notify_pid, true,
|
||||||
|
EffectiveEpochId);
|
||||||
|
Epoch /= EffectiveEpoch ->
|
||||||
|
%% This projection has an inner proj.
|
||||||
|
%% The outer proj is flapping, so we do
|
||||||
|
%% not bother wedging.
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
S#state{max_public_epochid=EpochId};
|
||||||
|
ProjType == private,
|
||||||
|
Epoch > element(1, S#state.max_private_epochid) ->
|
||||||
|
update_wedge_state(
|
||||||
|
S#state.wedge_notify_pid, false,
|
||||||
|
EffectiveEpochId),
|
||||||
|
S#state{max_private_epochid=EpochId};
|
||||||
|
true ->
|
||||||
|
S
|
||||||
|
end,
|
||||||
|
{ok, NewS}.
|
||||||
|
|
||||||
update_wedge_state(PidSpec, Boolean, {0,_}=EpochId) ->
|
update_wedge_state(PidSpec, Boolean, {0,_}=EpochId) ->
|
||||||
%% Epoch #0 is a special case: no projection has been written yet.
|
%% Epoch #0 is a special case: no projection has been written yet.
|
||||||
%% However, given the way that machi_flu_psup starts the
|
%% However, given the way that machi_flu_psup starts the
|
||||||
|
|
|
@ -41,6 +41,9 @@ smoke_test() ->
|
||||||
ok = ?PS:write(a_pstore, public, P1),
|
ok = ?PS:write(a_pstore, public, P1),
|
||||||
{error, written} = ?PS:write(a_pstore, public, P1),
|
{error, written} = ?PS:write(a_pstore, public, P1),
|
||||||
|
|
||||||
|
Pbad = P1#projection_v1{epoch_number=99238}, % break checksum
|
||||||
|
{error, bad_arg} = ?PS:write(a_pstore, public, Pbad),
|
||||||
|
|
||||||
ok = ?PS:write(a_pstore, private, P1),
|
ok = ?PS:write(a_pstore, private, P1),
|
||||||
{error, written} = ?PS:write(a_pstore, private, P1),
|
{error, written} = ?PS:write(a_pstore, private, P1),
|
||||||
P1b = P1#projection_v1{dbg2=[version_b]},
|
P1b = P1#projection_v1{dbg2=[version_b]},
|
||||||
|
|
Loading…
Reference in a new issue