Produce stacktraces unless mnesia_compatible #3
12
README.md
12
README.md
@ -131,6 +131,18 @@ depend on having an up to date size count at all times, you need to maintain
|
|||||||
it yourself. If you only need the size occasionally, you may traverse the
|
it yourself. If you only need the size occasionally, you may traverse the
|
||||||
table to count the elements.
|
table to count the elements.
|
||||||
|
|
||||||
|
When `mrdb` transactions abort, they will return a stacktrace caught
|
||||||
|
from within the transaction fun, giving much better debugging info.
|
||||||
|
This is different from how mnesia does it.
|
||||||
|
|
||||||
|
If behavior closer to mnesia's abort returns are needed, say, for backwards
|
||||||
|
compatibility, this can be controlled by setting the environment variable
|
||||||
|
`-mnesia_rocksdb mnesia_compatible_aborts true`, or by adding a transaction
|
||||||
|
option, e.g. `mrdb:activity({tx, #{mnesia_compatible => true}}, fun() ... end)`.
|
||||||
|
For really performance-critical transactions which may abort often, it might
|
||||||
|
make a difference to set this option to `true`, since there is a cost involved
|
||||||
|
in producing stacktraces.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Mnesia_backend_plugins">Mnesia backend plugins</a> ###
|
### <a name="Mnesia_backend_plugins">Mnesia backend plugins</a> ###
|
||||||
|
|
||||||
|
27
src/mrdb.erl
27
src/mrdb.erl
@ -297,14 +297,34 @@ do_activity(F, Alias, Ctxt) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
try_f(F, Ctxt) ->
|
try_f(F, Ctxt) ->
|
||||||
|
try_f(mnesia_compatible_aborts(Ctxt), F, Ctxt).
|
||||||
|
|
||||||
|
try_f(false, F, Ctxt) ->
|
||||||
try run_f(F, Ctxt) of
|
try run_f(F, Ctxt) of
|
||||||
Res ->
|
Res ->
|
||||||
commit_and_pop(Res)
|
commit_and_pop(Res)
|
||||||
catch
|
catch
|
||||||
|
throw:Something ->
|
||||||
|
abort_and_pop(throw, Something);
|
||||||
|
Cat:Err:T ->
|
||||||
|
%% Without capturing the stacktract here,
|
||||||
|
%% debugging gets pretty difficult. Incompatible with mnesia, though.
|
||||||
|
abort_and_pop(Cat, {Err, T})
|
||||||
|
end;
|
||||||
|
try_f(true, F, Ctxt) ->
|
||||||
|
try run_f(F, Ctxt) of
|
||||||
|
Res ->
|
||||||
|
commit_and_pop(Res)
|
||||||
|
catch
|
||||||
|
throw:Something ->
|
||||||
|
abort_and_pop(throw, Something);
|
||||||
Cat:Err ->
|
Cat:Err ->
|
||||||
|
%% Without capturing the stacktract here,
|
||||||
|
%% debugging gets pretty difficult
|
||||||
abort_and_pop(Cat, Err)
|
abort_and_pop(Cat, Err)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
run_f(F, Ctxt) ->
|
run_f(F, Ctxt) ->
|
||||||
push_ctxt(Ctxt),
|
push_ctxt(Ctxt),
|
||||||
F().
|
F().
|
||||||
@ -411,7 +431,7 @@ apply_tx_opts(Opts0) when is_map(Opts0) ->
|
|||||||
check_tx_opts(maps:merge(default_tx_opts(), Opts0)).
|
check_tx_opts(maps:merge(default_tx_opts(), Opts0)).
|
||||||
|
|
||||||
check_tx_opts(Opts) ->
|
check_tx_opts(Opts) ->
|
||||||
case maps:without([no_snapshot, retries], Opts) of
|
case maps:without([no_snapshot, retries, mnesia_compatible], Opts) of
|
||||||
Other when map_size(Other) > 0 ->
|
Other when map_size(Other) > 0 ->
|
||||||
abort({invalid_tx_opts, maps:keys(Other)});
|
abort({invalid_tx_opts, maps:keys(Other)});
|
||||||
_ ->
|
_ ->
|
||||||
@ -523,6 +543,11 @@ re_throw(Cat, Err) ->
|
|||||||
mnesia_compatible_aborts() ->
|
mnesia_compatible_aborts() ->
|
||||||
mnesia_rocksdb_admin:get_cached_env(mnesia_compatible_aborts, false).
|
mnesia_rocksdb_admin:get_cached_env(mnesia_compatible_aborts, false).
|
||||||
|
|
||||||
|
mnesia_compatible_aborts(#{activity := #{mnesia_compatible := Bool}}) ->
|
||||||
|
Bool;
|
||||||
|
mnesia_compatible_aborts(_) ->
|
||||||
|
mnesia_compatible_aborts().
|
||||||
|
|
||||||
fix_error({aborted, Err}) ->
|
fix_error({aborted, Err}) ->
|
||||||
Err;
|
Err;
|
||||||
fix_error(Err) ->
|
fix_error(Err) ->
|
||||||
|
@ -269,7 +269,7 @@ mrdb_abort(Config) ->
|
|||||||
Pre = mrdb:read(tx_abort, a),
|
Pre = mrdb:read(tx_abort, a),
|
||||||
D0 = get_dict(),
|
D0 = get_dict(),
|
||||||
TRes = try mrdb:activity(
|
TRes = try mrdb:activity(
|
||||||
tx, rdb,
|
{tx, #{mnesia_compatible => true}}, rdb,
|
||||||
fun() ->
|
fun() ->
|
||||||
[{tx_abort, a, N}] = mrdb:read(tx_abort, a),
|
[{tx_abort, a, N}] = mrdb:read(tx_abort, a),
|
||||||
error(abort_here),
|
error(abort_here),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user