Fix table load bug, fail properly on mnesia-ordered updates
This commit is contained in:
parent
d5dafb5b7e
commit
2339232f59
@ -168,6 +168,7 @@
|
|||||||
, alias
|
, alias
|
||||||
, tab
|
, tab
|
||||||
, type
|
, type
|
||||||
|
, on_error
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-type data_tab() :: atom().
|
-type data_tab() :: atom().
|
||||||
@ -445,8 +446,9 @@ create_table(Alias, Tab, Props) ->
|
|||||||
{ok, Pid} = maybe_start_proc(Alias, Tab, Props),
|
{ok, Pid} = maybe_start_proc(Alias, Tab, Props),
|
||||||
do_call(Pid, {create_table, Tab, Props}).
|
do_call(Pid, {create_table, Tab, Props}).
|
||||||
|
|
||||||
load_table(Alias, Tab, LoadReason, Opts) ->
|
load_table(Alias, Tab, LoadReason, Props) ->
|
||||||
call(Alias, Tab, {load_table, LoadReason, Opts}).
|
{ok, Pid} = maybe_start_proc(Alias, Tab, Props),
|
||||||
|
do_call(Pid, {load_table, LoadReason, Props}).
|
||||||
|
|
||||||
close_table(Alias, Tab) ->
|
close_table(Alias, Tab) ->
|
||||||
case mnesia_rocksdb_admin:get_ref(Tab, error) of
|
case mnesia_rocksdb_admin:get_ref(Tab, error) of
|
||||||
@ -594,10 +596,6 @@ delete(Alias, Tab, Key) ->
|
|||||||
legacy -> call(Alias, Tab, {delete, Key});
|
legacy -> call(Alias, Tab, {delete, Key});
|
||||||
R -> db_delete(R, Key, [], R)
|
R -> db_delete(R, Key, [], R)
|
||||||
end.
|
end.
|
||||||
%% call_if_legacy(Alias, Tab, {delete, Key}, fun() -> mrdb
|
|
||||||
%% mrdb:delete(Tab, Key).
|
|
||||||
%% %% opt_call(Alias, Tab, {delete, Key}),
|
|
||||||
%% %% ok.
|
|
||||||
|
|
||||||
first(_Alias, Tab) ->
|
first(_Alias, Tab) ->
|
||||||
mrdb:first(Tab).
|
mrdb:first(Tab).
|
||||||
@ -609,7 +607,7 @@ fixtable(_Alias, _Tab, _Bool) ->
|
|||||||
insert(Alias, Tab, Obj) ->
|
insert(Alias, Tab, Obj) ->
|
||||||
case access_type(Tab) of
|
case access_type(Tab) of
|
||||||
legacy -> call(Alias, Tab, {insert, Obj});
|
legacy -> call(Alias, Tab, {insert, Obj});
|
||||||
R -> db_insert(R, Obj, [], R)
|
R -> db_insert(R, Obj, [], [])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
last(_Alias, Tab) ->
|
last(_Alias, Tab) ->
|
||||||
@ -795,9 +793,9 @@ handle_call({create_table, Tab, Props}, _From,
|
|||||||
exit:{aborted, Error} ->
|
exit:{aborted, Error} ->
|
||||||
{reply, {aborted, Error}, St}
|
{reply, {aborted, Error}, St}
|
||||||
end;
|
end;
|
||||||
handle_call({load_table, _LoadReason, _Opts}, _From,
|
handle_call({load_table, _LoadReason, Props}, _From,
|
||||||
#st{alias = Alias, tab = Tab} = St) ->
|
#st{alias = Alias, tab = Tab} = St) ->
|
||||||
ok = mnesia_rocksdb_admin:load_table(Alias, Tab),
|
ok = mnesia_rocksdb_admin:load_table(Alias, Tab, Props),
|
||||||
{reply, ok, St};
|
{reply, ok, St};
|
||||||
handle_call({write_info, Key, Value}, _From, #st{ref = Ref} = St) ->
|
handle_call({write_info, Key, Value}, _From, #st{ref = Ref} = St) ->
|
||||||
mrdb:write_info(Ref, Key, Value),
|
mrdb:write_info(Ref, Key, Value),
|
||||||
@ -869,11 +867,11 @@ do_call(P, Req) ->
|
|||||||
|
|
||||||
%% server-side end of insert/3.
|
%% server-side end of insert/3.
|
||||||
do_insert(Obj, #st{ref = Ref} = St) ->
|
do_insert(Obj, #st{ref = Ref} = St) ->
|
||||||
return_catch(fun() -> db_insert(Ref, Obj, [], St) end).
|
db_insert(Ref, Obj, [], St).
|
||||||
|
|
||||||
%% server-side part
|
%% server-side part
|
||||||
do_delete(Key, #st{ref = Ref} = St) ->
|
do_delete(Key, #st{ref = Ref} = St) ->
|
||||||
return_catch(fun() -> db_delete(Ref, Key, [], St) end).
|
db_delete(Ref, Key, [], St).
|
||||||
|
|
||||||
proc_name(_Alias, Tab) ->
|
proc_name(_Alias, Tab) ->
|
||||||
list_to_atom("mnesia_ext_proc_" ++ mnesia_rocksdb_lib:tabname(Tab)).
|
list_to_atom("mnesia_ext_proc_" ++ mnesia_rocksdb_lib:tabname(Tab)).
|
||||||
@ -885,21 +883,30 @@ whereis_proc(Alias, Tab) ->
|
|||||||
%% Db wrappers
|
%% Db wrappers
|
||||||
%% ----------------------------------------------------------------------------
|
%% ----------------------------------------------------------------------------
|
||||||
|
|
||||||
return_catch(F) when is_function(F, 0) ->
|
db_insert(Ref, Obj, Opts, St) ->
|
||||||
try F()
|
try mrdb:insert(Ref, Obj, Opts) of
|
||||||
|
ok -> ok;
|
||||||
|
{error, _} = Error ->
|
||||||
|
write_error(insert, [Ref, Obj, Opts], Error, St)
|
||||||
catch
|
catch
|
||||||
throw:badarg ->
|
Cat:Exception:T ->
|
||||||
badarg
|
write_error(insert, [Ref, Obj, Opts], {Cat, Exception, T}, St)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
db_insert(Ref, Obj, Opts, St) ->
|
|
||||||
write_result(mrdb:insert(Ref, Obj, Opts), insert, [Ref, Obj, Opts], St).
|
|
||||||
|
|
||||||
db_delete(Ref, K, Opts, St) ->
|
db_delete(Ref, K, Opts, St) ->
|
||||||
write_result(mrdb:delete(Ref, K, Opts), delete, [Ref, K, Opts], St).
|
try mrdb:delete(Ref, K, Opts) of
|
||||||
|
ok -> ok;
|
||||||
|
{error, _} = Error ->
|
||||||
|
write_error(delete, [Ref, K, Opts], Error, St)
|
||||||
|
catch
|
||||||
|
Cat:Exception:T ->
|
||||||
|
write_error(delete, [Ref, K, Opts], {Cat, Exception, T}, St)
|
||||||
|
end.
|
||||||
|
|
||||||
write_result(ok, _, _, _) ->
|
write_error(_Op, _Args, _Error, #st{on_error = OnErr}) when OnErr =/= fatal ->
|
||||||
ok.
|
ok;
|
||||||
|
write_error(Op, Args, Error, _) ->
|
||||||
|
mnesia:fatal("mnesia_rocksdb write_error: ~p ~p -> ~p", [Op, Args, Error]).
|
||||||
|
|
||||||
%% ----------------------------------------------------------------------------
|
%% ----------------------------------------------------------------------------
|
||||||
%% COMMON PRIVATE
|
%% COMMON PRIVATE
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
, remove_aliases/1
|
, remove_aliases/1
|
||||||
, create_table/3 %% (Alias, Name, Props) -> {ok, Ref} | error()
|
, create_table/3 %% (Alias, Name, Props) -> {ok, Ref} | error()
|
||||||
, delete_table/2 %% (Alias, Name) -> ok
|
, delete_table/2 %% (Alias, Name) -> ok
|
||||||
, load_table/2 %% (Alias, Name) -> ok
|
, load_table/3 %% (Alias, Name, Props) -> ok
|
||||||
, related_resources/2 %% (Alias, Name) -> [RelatedTab]
|
, related_resources/2 %% (Alias, Name) -> [RelatedTab]
|
||||||
, prep_close/2 %% (Alias, Tab) -> ok
|
, prep_close/2 %% (Alias, Tab) -> ok
|
||||||
, get_ref/1 %% (Name) -> Ref | abort()
|
, get_ref/1 %% (Name) -> Ref | abort()
|
||||||
@ -143,8 +143,8 @@ create_table(Alias, Name, Props) ->
|
|||||||
delete_table(Alias, Name) ->
|
delete_table(Alias, Name) ->
|
||||||
call(Alias, {delete_table, Name}).
|
call(Alias, {delete_table, Name}).
|
||||||
|
|
||||||
load_table(Alias, Name) ->
|
load_table(Alias, Name, Props) ->
|
||||||
call(Alias, {load_table, Name}).
|
call(Alias, {load_table, Name, Props}).
|
||||||
|
|
||||||
related_resources(Alias, Name) ->
|
related_resources(Alias, Name) ->
|
||||||
if is_atom(Name) ->
|
if is_atom(Name) ->
|
||||||
@ -463,24 +463,32 @@ handle_req(Alias, {create_table, Name, Props}, Backend, St) ->
|
|||||||
{error, _} = Error ->
|
{error, _} = Error ->
|
||||||
{reply, Error, St}
|
{reply, Error, St}
|
||||||
end;
|
end;
|
||||||
handle_req(Alias, {load_table, Name}, Backend, St) ->
|
handle_req(Alias, {load_table, Name, Props}, Backend, St) ->
|
||||||
|
?log(debug, "load_table, ~p, ~p", [Name, Props]),
|
||||||
|
try
|
||||||
case find_cf(Alias, Name, Backend, St) of
|
case find_cf(Alias, Name, Backend, St) of
|
||||||
{ok, #{status := open}} ->
|
{ok, #{status := open}} ->
|
||||||
?log(info, "load_table(~p) when table already loaded", [Name]),
|
?log(info, "load_table(~p) when table already loaded", [Name]),
|
||||||
{reply, ok, St};
|
{reply, ok, St};
|
||||||
{ok, TRec} ->
|
{ok, #{status := created} = TRec} ->
|
||||||
case create_table_from_trec(Alias, Name, TRec, Backend, St) of
|
handle_load_table_req(Alias, Name, TRec, Backend, St);
|
||||||
{ok, TRec1, St1} ->
|
_ ->
|
||||||
TRec2 = TRec1#{status => open},
|
?log(debug, "load_table (~p) without preceding create_table", [Name]),
|
||||||
St2 = update_cf(Alias, Name, TRec2, St1),
|
case create_trec(Alias, Name, Props, Backend, St) of
|
||||||
?log(debug, "Table loaded ~p", [Name]),
|
{ok, NewCf} ->
|
||||||
put_pt(Name, TRec2),
|
?log(debug, "NewCf = ~p", [NewCf]),
|
||||||
{reply, ok, St2};
|
St1 = update_cf(Alias, Name, NewCf, St),
|
||||||
|
Backend1 = maps:get(Alias, St1#st.backends),
|
||||||
|
{ok, TRec} = find_cf(Alias, Name, Backend1, St1),
|
||||||
|
handle_load_table_req(Alias, Name, TRec, Backend1, St1);
|
||||||
{error, _} = Error ->
|
{error, _} = Error ->
|
||||||
{reply, Error, St}
|
{reply, {abort, Error}, St}
|
||||||
end;
|
end
|
||||||
error ->
|
end
|
||||||
{reply, {abort, {bad_type, Name}}, St}
|
catch
|
||||||
|
error:E:ST ->
|
||||||
|
?log(error, "CAUGHT error:~p (Tab: ~p) / ~p", [E, Name, ST]),
|
||||||
|
{reply, {error, E}, St}
|
||||||
end;
|
end;
|
||||||
handle_req(_Alias, {prep_close, Name}, Backend, St) ->
|
handle_req(_Alias, {prep_close, Name}, Backend, St) ->
|
||||||
ok_reply(do_prep_close(Name, Backend, St), St);
|
ok_reply(do_prep_close(Name, Backend, St), St);
|
||||||
@ -533,6 +541,17 @@ handle_req(Alias, {migrate, Tabs0}, Backend, St) ->
|
|||||||
{reply, Error, St}
|
{reply, Error, St}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
handle_load_table_req(Alias, Name, TRec, Backend, St) ->
|
||||||
|
case create_table_from_trec(Alias, Name, TRec, Backend, St) of
|
||||||
|
{ok, TRec1, St1} ->
|
||||||
|
TRec2 = TRec1#{status => open},
|
||||||
|
St2 = update_cf(Alias, Name, TRec2, St1),
|
||||||
|
?log(debug, "Table loaded ~p", [Name]),
|
||||||
|
put_pt(Name, TRec2),
|
||||||
|
{reply, ok, St2};
|
||||||
|
{error, _} = Error ->
|
||||||
|
{reply, Error, St}
|
||||||
|
end.
|
||||||
|
|
||||||
%% if an index table has been created or deleted, make sure the main
|
%% if an index table has been created or deleted, make sure the main
|
||||||
%% ref reflects it.
|
%% ref reflects it.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user