enforce gm GROUP_TABLE abstraction
...by using mnesia:write/3 instead of /1 and generally abstract mnesia reading/writing and make it dirty reads obvious.
This commit is contained in:
parent
1b6a32995b
commit
aa2f796b06
36
src/gm.erl
36
src/gm.erl
|
@ -636,7 +636,7 @@ handle_cast({?TAG, ReqVer, Msg},
|
||||||
callback_args = Args }) ->
|
callback_args = Args }) ->
|
||||||
{Result, State1} =
|
{Result, State1} =
|
||||||
case needs_view_update(ReqVer, View) of
|
case needs_view_update(ReqVer, View) of
|
||||||
true -> View1 = group_to_view(read_group(GroupName)),
|
true -> View1 = group_to_view(dirty_read_group(GroupName)),
|
||||||
MemberState1 = remove_erased_members(MembersState, View1),
|
MemberState1 = remove_erased_members(MembersState, View1),
|
||||||
{callback_view_changed(Args, Module, View, View1),
|
{callback_view_changed(Args, Module, View, View1),
|
||||||
check_neighbours(
|
check_neighbours(
|
||||||
|
@ -1037,7 +1037,7 @@ ensure_alive_suffix1(MembersQ) ->
|
||||||
%% ---------------------------------------------------------------------------
|
%% ---------------------------------------------------------------------------
|
||||||
|
|
||||||
join_group(Self, GroupName, TxnFun) ->
|
join_group(Self, GroupName, TxnFun) ->
|
||||||
join_group(Self, GroupName, read_group(GroupName), TxnFun).
|
join_group(Self, GroupName, dirty_read_group(GroupName), TxnFun).
|
||||||
|
|
||||||
join_group(Self, GroupName, {error, not_found}, TxnFun) ->
|
join_group(Self, GroupName, {error, not_found}, TxnFun) ->
|
||||||
join_group(Self, GroupName,
|
join_group(Self, GroupName,
|
||||||
|
@ -1080,27 +1080,29 @@ join_group(Self, GroupName, #gm_group { members = Members } = Group, TxnFun) ->
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
read_group(GroupName) ->
|
dirty_read_group(GroupName) ->
|
||||||
case mnesia:dirty_read(?GROUP_TABLE, GroupName) of
|
case mnesia:dirty_read(?GROUP_TABLE, GroupName) of
|
||||||
[] -> {error, not_found};
|
[] -> {error, not_found};
|
||||||
[Group] -> Group
|
[Group] -> Group
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
read_group(GroupName) -> mnesia:read({?GROUP_TABLE, GroupName}).
|
||||||
|
|
||||||
|
write_group(Group) -> mnesia:write(?GROUP_TABLE, Group, write), Group.
|
||||||
|
|
||||||
prune_or_create_group(Self, GroupName, TxnFun) ->
|
prune_or_create_group(Self, GroupName, TxnFun) ->
|
||||||
Group = TxnFun(
|
Group = TxnFun(
|
||||||
fun () ->
|
fun () ->
|
||||||
GroupNew = #gm_group { name = GroupName,
|
GroupNew = #gm_group { name = GroupName,
|
||||||
members = [Self],
|
members = [Self],
|
||||||
version = get_version(Self) },
|
version = get_version(Self) },
|
||||||
case mnesia:read({?GROUP_TABLE, GroupName}) of
|
case read_group(GroupName) of
|
||||||
[] ->
|
[] ->
|
||||||
mnesia:write(GroupNew),
|
write_group(GroupNew);
|
||||||
GroupNew;
|
|
||||||
[Group1 = #gm_group { members = Members }] ->
|
[Group1 = #gm_group { members = Members }] ->
|
||||||
case lists:any(fun is_member_alive/1, Members) of
|
case lists:any(fun is_member_alive/1, Members) of
|
||||||
true -> Group1;
|
true -> Group1;
|
||||||
false -> mnesia:write(GroupNew),
|
false -> write_group(GroupNew)
|
||||||
GroupNew
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end),
|
end),
|
||||||
|
@ -1117,10 +1119,8 @@ record_dead_member_in_group(Member, GroupName, TxnFun) ->
|
||||||
Group1;
|
Group1;
|
||||||
{Members1, [Member | Members2]} ->
|
{Members1, [Member | Members2]} ->
|
||||||
Members3 = Members1 ++ [{dead, Member} | Members2],
|
Members3 = Members1 ++ [{dead, Member} | Members2],
|
||||||
Group2 = Group1 #gm_group { members = Members3,
|
write_group(Group1 #gm_group { members = Members3,
|
||||||
version = Ver + 1 },
|
version = Ver + 1 })
|
||||||
mnesia:write(Group2),
|
|
||||||
Group2
|
|
||||||
end
|
end
|
||||||
end),
|
end),
|
||||||
Group.
|
Group.
|
||||||
|
@ -1136,9 +1136,7 @@ record_new_member_in_group(GroupName, Left, NewMember, Fun, TxnFun) ->
|
||||||
Members1 = Prefix ++ [Left, NewMember | Suffix],
|
Members1 = Prefix ++ [Left, NewMember | Suffix],
|
||||||
Group2 = Group1 #gm_group { members = Members1,
|
Group2 = Group1 #gm_group { members = Members1,
|
||||||
version = Ver + 1 },
|
version = Ver + 1 },
|
||||||
Result = Fun(Group2),
|
{Fun(Group2), write_group(Group2)}
|
||||||
mnesia:write(Group2),
|
|
||||||
{Result, Group2}
|
|
||||||
end),
|
end),
|
||||||
{Result, Group}.
|
{Result, Group}.
|
||||||
|
|
||||||
|
@ -1152,11 +1150,9 @@ erase_members_in_group(Members, GroupName, TxnFun) ->
|
||||||
mnesia:read({?GROUP_TABLE, GroupName}),
|
mnesia:read({?GROUP_TABLE, GroupName}),
|
||||||
case Members1 -- DeadMembers of
|
case Members1 -- DeadMembers of
|
||||||
Members1 -> Group1;
|
Members1 -> Group1;
|
||||||
Members2 -> Group2 =
|
Members2 -> write_group(
|
||||||
Group1 #gm_group { members = Members2,
|
Group1 #gm_group { members = Members2,
|
||||||
version = Ver + 1 },
|
version = Ver + 1 })
|
||||||
mnesia:write(Group2),
|
|
||||||
Group2
|
|
||||||
end
|
end
|
||||||
end),
|
end),
|
||||||
Group.
|
Group.
|
||||||
|
@ -1321,7 +1317,7 @@ prepare_members_state(MembersState) -> ?DICT:to_list(MembersState).
|
||||||
build_members_state(MembersStateList) -> ?DICT:from_list(MembersStateList).
|
build_members_state(MembersStateList) -> ?DICT:from_list(MembersStateList).
|
||||||
|
|
||||||
make_member(GroupName) ->
|
make_member(GroupName) ->
|
||||||
{case read_group(GroupName) of
|
{case dirty_read_group(GroupName) of
|
||||||
#gm_group { version = Version } -> Version;
|
#gm_group { version = Version } -> Version;
|
||||||
{error, not_found} -> ?VERSION_START
|
{error, not_found} -> ?VERSION_START
|
||||||
end, self()}.
|
end, self()}.
|
||||||
|
|
Loading…
Reference in New Issue