Skip to content

Commit 99ec5e5

Browse files
authored
Addressing Mnesia backend failing on erldns_zone_cache functions (#103)
* Addressing Mnesia backend failing on erldns_zone_cache functions: * added type bag on table creation (zone_records, zone_records_typed) * set explicit type set on table creation (zones) * refactored select/3: using ETS match spec converted to Mnesia's match_object pattern * Mnesia related changes: * using different pattern in erldns_zone_cache:zone_names_and_versions/0 depending on backend (ETS/Mnesia foldl/3 return values are different) * debug artefacts cleanup * * refactored erldns_zone_cache:get_records_by_name to call erldns_storage:select/3 vs select/2 * added flattening returned from the select/3
1 parent e153295 commit 99ec5e5

File tree

3 files changed

+30
-14
lines changed

3 files changed

+30
-14
lines changed

src/erldns_storage.erl

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
terminate/2,
4444
code_change/3]).
4545

46-
4746
-record(state, {}).
4847

4948
-define(POLL_WAIT_HOURS, 1).

src/erldns_storage_mnesia.erl

+22-8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ create(zones) ->
7272
case mnesia:create_table(zones,
7373
[{attributes, record_info(fields, zone)},
7474
{record_name, zone},
75+
{type, set},
7576
{disc_copies, [node()]}]) of
7677
{aborted, {already_exists, zones}} ->
7778
lager:warning("The zone table already exists (node: ~p)", [node()]),
@@ -84,7 +85,9 @@ create(zones) ->
8485
create(zone_records) ->
8586
case mnesia:create_table(zone_records,
8687
[{attributes, record_info(fields, zone_records)},
87-
{disc_copies, [node()]}]) of
88+
{disc_copies, [node()]},
89+
{type, bag}
90+
]) of
8891
{aborted, {already_exists, zone_records}} ->
8992
lager:warning("The zone records table already exists (node: ~p)", [node()]),
9093
ok;
@@ -96,9 +99,11 @@ create(zone_records) ->
9699
create(zone_records_typed) ->
97100
case mnesia:create_table(zone_records_typed,
98101
[{attributes, record_info(fields, zone_records_typed)},
99-
{disc_copies, [node()]}]) of
102+
{disc_copies, [node()]},
103+
{type, bag}
104+
]) of
100105
{aborted, {already_exists, zone_records_typed}} ->
101-
lager:warning("The zone records table already exists (node: ~p)", [node()]),
106+
lager:warning("The zone records typed table already exists (node: ~p)", [node()]),
102107
ok;
103108
{atomic, ok} ->
104109
ok;
@@ -192,7 +197,7 @@ delete(Table, Key)->
192197
-spec select_delete(atom(), list()) -> {ok, Count :: integer()} | {error, Reason :: term()}.
193198
select_delete(Table, [{{{ZoneName, Fqdn}, _}, _, _}])->
194199
SelectDelete = fun() ->
195-
Records = mnesia:match_object(Table, {zone_records, ZoneName, Fqdn, '_'}, write),
200+
Records = mnesia:match_object(Table, {zone_records, ZoneName, Fqdn, '_'}, read),
196201
lists:foreach(fun(R) -> mnesia:dirty_delete_object(R) end, Records),
197202
{ok, length(Records)}
198203
end,
@@ -229,11 +234,20 @@ select(Table, Key)->
229234
end,
230235
mnesia:activity(transaction, Select).
231236

232-
%% @doc Select using a match spec.
237+
%% @doc Select using ETS match spec converted to Mnesia's match_object pattern
233238
-spec select(atom(), list(), infinite | integer()) -> [tuple()].
234-
select(_Table, MatchSpec, _Limit) ->
235-
MatchObject = fun() -> mnesia:match_object(MatchSpec) end,
236-
mnesia:activity(transaction, MatchObject).
239+
select(Table, [{{{ZoneName, Fqdn}, _}, _, _}], _Limit) ->
240+
SelectFun = fun() ->
241+
Records = mnesia:match_object(Table, {zone_records, ZoneName, Fqdn, '_'}, read),
242+
[Record || {_, _, _, Record} <- Records]
243+
end,
244+
mnesia:activity(transaction, SelectFun);
245+
select(Table, [{{{ZoneName, Fqdn, Type}, _}, _, _}], _Limit) ->
246+
SelectFun = fun() ->
247+
Records = mnesia:match_object(Table, {zone_records_typed, ZoneName, Fqdn, Type, '_'}, read),
248+
[Record || {_, _, _, _, Record} <- Records]
249+
end,
250+
mnesia:activity(transaction, SelectFun).
237251

238252
%% @doc Wrapper for foldl.
239253
-spec foldl(fun(), list(), atom()) -> Acc :: term() | {error, Reason :: term()}.

src/erldns_zone_cache.erl

+8-5
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,7 @@ get_records_by_name_and_type(Name, Type) ->
170170
get_records_by_name(Name) ->
171171
case find_zone_in_cache(Name) of
172172
{ok, Zone} ->
173-
case erldns_storage:select(zone_records, {erldns:normalize_name(Zone#zone.name), erldns:normalize_name(Name)}) of
174-
[] -> [];
175-
[{_, Records}] -> Records
176-
end;
173+
lists:flatten(erldns_storage:select(zone_records,[{{{erldns:normalize_name(Zone#zone.name), erldns:normalize_name(Name)}, '$1'},[],['$$']}], infinite));
177174
_ ->
178175
[]
179176
end.
@@ -192,7 +189,13 @@ in_zone(Name) ->
192189
%% for the zone.
193190
-spec zone_names_and_versions() -> [{dns:dname(), binary()}].
194191
zone_names_and_versions() ->
195-
erldns_storage:foldl(fun({_, Zone}, NamesAndShas) -> NamesAndShas ++ [{Zone#zone.name, Zone#zone.version}] end, [], zones).
192+
% ETS and Mnesia foldl/3 differ in return values -> Mnesia's version is missing key
193+
case erldns_config:storage_type() of
194+
erldns_storage_json ->
195+
erldns_storage:foldl(fun({_, Zone}, NamesAndShas) -> NamesAndShas ++ [{Zone#zone.name, Zone#zone.version}] end, [], zones);
196+
erldns_storage_mnesia ->
197+
erldns_storage:foldl(fun(Zone, NamesAndShas) -> NamesAndShas ++ [{Zone#zone.name, Zone#zone.version}] end, [], zones)
198+
end.
196199

197200
% ----------------------------------------------------------------------------------------------------
198201
% Write API

0 commit comments

Comments
 (0)