Created
April 18, 2018 13:58
-
-
Save hairyhum/2d66335b05e13637024b0bc69a522480 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(mnesia_consensus). | |
-behaviour(mnesia_access). | |
%% Mnesia access callbacks. | |
%% When mnesia:Fun is called inside an activity - it calls a module callback. | |
%% The callback can forward the call to the next level or do anything. | |
-export([ | |
lock/4, | |
write/5, delete/5, delete_object/5, | |
read/5, match_object/5, all_keys/4, | |
select/5,select/6,select_cont/3, | |
index_match_object/6, index_read/6, | |
foldl/6, foldr/6, table_info/4, | |
first/3, next/4, prev/4, last/3, | |
clear_table/4 | |
]). | |
consensus_transaction(Fun, Args) -> | |
start_transaction_context(), | |
%% Execute Fun in the mnesia_consensus context | |
%% This will collect writes and locks to apply after | |
%% transaction | |
Res = mnesia:activity(ets, Fun, Args, mnesia_consensus), | |
case good_res(Res) of | |
true -> | |
%% This thing should contain writes and updates. | |
%% May be recovered using ETS or the process dictionary | |
TransactionCtx = get_transaction_context()), | |
%% Make sure quorum of nodes agrees on the changes | |
case consensus_commit(TransactionCtx) of | |
ok -> Res; | |
%% Retry entire transaction. | |
not_ok -> retry_transaction(Fun, Args) | |
end; | |
false -> | |
retry_transaction(Fun, Args) | |
end. | |
%% This can be optimised by aborting the activity on locks. | |
%% That will cause activity to re-run and eventually produce | |
%% a valid transaction context to apply. | |
%% Example of read function just forwarding the call | |
read(ActivityId, Opaque, Tab, Key, LockKind) -> | |
mnesia:read(ActivityId, Opaque, Tab, Key, LockKind). | |
%% Example of write function. | |
%% Do not do an actual write here. | |
write(ActivityId, Opaque, Tab, Rec, LockKind) -> | |
record_consensus_lock(ActivityId, Tab, Rec, LockKind), | |
record_consensus_write(ActivityId, Tab, Rec, LockKind). | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment