diff --git a/include/antidote.hrl b/include/antidote.hrl index 81623babb..fd1555619 100644 --- a/include/antidote.hrl +++ b/include/antidote.hrl @@ -215,15 +215,13 @@ -type crdt() :: term(). -type val() :: term(). -type reason() :: atom(). -%%chash:index_as_int() is the same as riak_core_apl:index(). -%%If it is changed in the future this should be fixed also. --type index_node() :: {chash:index_as_int(), node()}. +-type index_node() :: {any(), node()}. -type preflist() :: riak_core_apl:preflist(). -type log() :: term(). -type op_num() :: non_neg_integer(). -type op_id() :: {op_num(), node()}. -type payload() :: term(). --type partition_id() :: ets:tid() | integer(). % TODO 19 adding integer basically makes the tid type non-opaque, because some places of the code depend on it being an integer. This dependency should be removed, if possible. +-type partition_id() :: ets:tid() | non_neg_integer(). % TODO 19 adding integer basically makes the tid type non-opaque, because some places of the code depend on it being an integer. This dependency should be removed, if possible. -type log_id() :: [partition_id()]. -type bucket() :: term(). -type snapshot() :: term(). diff --git a/rebar.config b/rebar.config index 96476bfea..d3bc83e00 100644 --- a/rebar.config +++ b/rebar.config @@ -36,10 +36,13 @@ {eunit_opts, [verbose, {report, {eunit_surefire, [{dir, "logs/"}]}}]}. {dialyzer, [{warnings, [ - %unmatched_returns, + error_handling, + race_conditions, + %underspecs, + unmatched_returns %unknown %overspecs, - no_undefined_callbacks + %specdiffs ]}]}. {edoc_opts, [ @@ -50,7 +53,6 @@ ]}. {overrides, [ - %% R20 {override, riak_ensemble, [{erl_opts, [ debug_info, diff --git a/src/antidote.erl b/src/antidote.erl index 3ee126712..c4807ce78 100644 --- a/src/antidote.erl +++ b/src/antidote.erl @@ -55,11 +55,11 @@ %% Public API --spec start() -> {ok, _} | {error, term()}. +-spec start() -> {ok, [atom()]} | {error, reason()}. start() -> application:ensure_all_started(antidote). --spec stop() -> ok. +-spec stop() -> ok | {error, reason()}. stop() -> application:stop(antidote). diff --git a/src/antidote_dc_manager.erl b/src/antidote_dc_manager.erl index afd720d94..8bfb46764 100644 --- a/src/antidote_dc_manager.erl +++ b/src/antidote_dc_manager.erl @@ -54,7 +54,7 @@ create_dc(Nodes) -> logger:info("Creating DC ring ~p", [Nodes]), %% Ensure each node owns 100% of it's own ring - [[Node] = owners_according_to(Node) || Node <- Nodes], + _ = [[Node] = owners_according_to(Node) || Node <- Nodes], %% Join nodes [Node1|OtherNodes] = Nodes, case OtherNodes of @@ -75,7 +75,7 @@ create_dc(Nodes) -> wait_until_nodes_agree_about_ownership(Nodes), ok = wait_until_no_pending_changes(Nodes), wait_until_ring_converged(Nodes), - wait_until(hd(Nodes), fun wait_init:check_ready/1), + ok = wait_until(hd(Nodes), fun wait_init:check_ready/1), %% starts metadata services needed for intra-dc communication ok = inter_dc_manager:start_bg_processes(stable), ok. @@ -161,17 +161,16 @@ maybe_wait_for_changes(Node) -> %% @doc Given a list of nodes, wait until all nodes believe there are no %% on-going or pending ownership transfers. --spec wait_until_no_pending_changes([node()]) -> ok | fail. +-spec wait_until_no_pending_changes([node()]) -> ok. wait_until_no_pending_changes(Nodes) -> logger:info("Wait until no pending changes on ~p", [Nodes]), F = fun() -> - rpc:multicall(Nodes, riak_core_vnode_manager, force_handoffs, []), + _ = rpc:multicall(Nodes, riak_core_vnode_manager, force_handoffs, []), {Rings, BadNodes} = rpc:multicall(Nodes, riak_core_ring_manager, get_raw_ring, []), Changes = [ riak_core_ring:pending_changes(Ring) =:= [] || {ok, Ring} <- Rings ], BadNodes =:= [] andalso length(Changes) =:= length(Nodes) andalso lists:all(fun(T) -> T end, Changes) end, - ok = wait_until(F), - ok. + wait_until(F). %% @doc Utility function used to construct test predicates. Retries the %% function `Fun' until it returns `true', or until the maximum diff --git a/src/antidote_hooks.erl b/src/antidote_hooks.erl index 5bce0cf9f..cd8793a3c 100644 --- a/src/antidote_hooks.erl +++ b/src/antidote_hooks.erl @@ -79,12 +79,12 @@ -define(PREFIX_POST, {commit_hooks, post}). -spec register_post_hook(bucket(), module_name(), function_name()) -> - ok | {error, reason()}. + ok | {error, function_not_exported}. register_post_hook(Bucket, Module, Function) -> register_hook(?PREFIX_POST, Bucket, Module, Function). -spec register_pre_hook(bucket(), module_name(), function_name()) -> - ok | {error, reason()}. + ok | {error, function_not_exported}. register_pre_hook(Bucket, Module, Function) -> register_hook(?PREFIX_PRE, Bucket, Module, Function). diff --git a/src/antidote_stats_collector.erl b/src/antidote_stats_collector.erl index a4ad21d11..033cc8fd4 100644 --- a/src/antidote_stats_collector.erl +++ b/src/antidote_stats_collector.erl @@ -62,8 +62,8 @@ handle_cast(_Req, State) -> {noreply, State}. handle_info(periodic_update, OldTimer) -> - erlang:cancel_timer(OldTimer), - update_staleness(), + _ = erlang:cancel_timer(OldTimer), + _ = update_staleness(), Timer = erlang:send_after(?INTERVAL, self(), periodic_update), {noreply, Timer}. diff --git a/src/bcounter_mgr.erl b/src/bcounter_mgr.erl index 566996cf9..e3e86f552 100644 --- a/src/bcounter_mgr.erl +++ b/src/bcounter_mgr.erl @@ -107,7 +107,8 @@ handle_cast({transfer, {Key, Amount, Requester}}, #state{last_transfers=LT}=Stat true -> {SKey, Bucket} = Key, BObj = {SKey, ?DATA_TYPE, Bucket}, - antidote:update_objects(ignore, [], [{BObj, transfer, {Amount, Requester, MyDCId}}]), + % try to transfer locks, might return {error,no_permissions} if not enough permissions are available locally + _ = antidote:update_objects(ignore, [], [{BObj, transfer, {Amount, Requester, MyDCId}}]), {noreply, State#state{last_transfers=orddict:store({Key, Requester}, erlang:timestamp(), NewLT)}}; _ -> {noreply, State#state{last_transfers=NewLT}} @@ -125,7 +126,7 @@ handle_call({consume, Key, {Op, {Amount, _}}, BCounter}, _From, #state{req_queue end. handle_info(transfer_periodic, #state{req_queue=RQ0, transfer_timer=OldTimer}=State) -> - erlang:cancel_timer(OldTimer), + _ = erlang:cancel_timer(OldTimer), RQ = clear_pending_req(RQ0, ?REQUEST_TIMEOUT), RQNew = orddict:fold( fun(Key, Queue, Accum) -> diff --git a/src/clocksi_interactive_coord.erl b/src/clocksi_interactive_coord.erl index 3f1b8ee65..f190fe891 100644 --- a/src/clocksi_interactive_coord.erl +++ b/src/clocksi_interactive_coord.erl @@ -659,7 +659,7 @@ init_state(StayAlive, FullCommit, IsStatic, Properties) -> %% @doc TODO start_tx_internal(From, ClientClock, Properties, State = #coord_state{stay_alive = StayAlive, is_static = IsStatic}) -> {Transaction, TransactionId} = create_transaction_record(ClientClock, StayAlive, From, false, Properties), - case IsStatic of + _ = case IsStatic of true -> ok; false -> From ! {ok, TransactionId} end, @@ -807,17 +807,17 @@ prepare_2pc(State = #coord_state{ %% @doc when the transaction has committed or aborted, %% a reply is sent to the client that started the transaction. reply_to_client(State = #coord_state{ - from=From, - state=TxState, - is_static=IsStatic, - stay_alive=StayAlive, - client_ops=ClientOps, - commit_time=CommitTime, - full_commit=FullCommit, - transaction=Transaction, - return_accumulator=ReturnAcc -}) -> - case From of + from=From, + state=TxState, + is_static=IsStatic, + stay_alive=StayAlive, + client_ops=ClientOps, + commit_time=CommitTime, + full_commit=FullCommit, + transaction=Transaction, + return_accumulator=ReturnAcc + }) -> + _ = case From of undefined -> ok; diff --git a/src/clocksi_readitem_server.erl b/src/clocksi_readitem_server.erl index f40431ac0..22d4dd43c 100644 --- a/src/clocksi_readitem_server.erl +++ b/src/clocksi_readitem_server.erl @@ -65,7 +65,7 @@ self :: atom()}). -type read_property_list() :: []. - +-export_type([read_property_list/0]). %%%=================================================================== %%% API %%%=================================================================== diff --git a/src/dc_utilities.erl b/src/dc_utilities.erl index d2ff53b75..ddc3630e0 100644 --- a/src/dc_utilities.erl +++ b/src/dc_utilities.erl @@ -274,7 +274,7 @@ get_stable_snapshot() -> end end. --spec get_partition_snapshot(partition_id()) -> snapshot_time(). +-spec get_partition_snapshot(partition_id()) -> vectorclock:vectorclock(). get_partition_snapshot(Partition) -> case meta_data_sender:get_meta(stable_time_functions, Partition, vectorclock:new()) of undefined -> @@ -299,7 +299,7 @@ get_scalar_stable_time() -> Now = dc_utilities:now_microsec() - ?OLD_SS_MICROSEC, {ok, Now, StableSnapshot}; _ -> - DCs = dc_meta_data_utilites:get_dc_ids(true), + DCs = dc_meta_data_utilities:get_dc_ids(true), GST = vectorclock:min_clock(StableSnapshot, DCs), {ok, GST, vectorclock:set_all(GST, StableSnapshot)} end. diff --git a/src/logging_vnode.erl b/src/logging_vnode.erl index 8471c96fa..d3ec68b48 100644 --- a/src/logging_vnode.erl +++ b/src/logging_vnode.erl @@ -80,8 +80,10 @@ -ignore_xref([start_vnode/1]). +-type disklog() :: term(). %Actually: disklog(), which is not exported + -record(state, {partition :: partition_id(), - logs_map :: dict:dict(log_id(), disk_log:log()), + logs_map :: dict:dict(log_id(), disklog()), enable_log_to_disk :: boolean(), %% this enables or disables logging to disk. op_id_table :: cache_id(), %% Stores the count of ops appended to each log recovered_vector :: vectorclock(), %% This is loaded on start, storing the version vector @@ -865,7 +867,7 @@ terminate(_Reason, _State) -> %% Return: true if all logs are empty. false if at least one log %% contains data. %% --spec no_elements([log_id()], dict:dict(log_id(), disk_log:log())) -> boolean(). +-spec no_elements([log_id()], dict:dict(log_id(), disklog())) -> boolean(). no_elements([], _Map) -> true; no_elements([LogId|Rest], Map) -> @@ -893,7 +895,7 @@ no_elements([LogId|Rest], Map) -> %% the log in the system. dict:dict() type. %% MaxVector: The version vector time of the last %% operation appended to the logs --spec open_logs(string(), [preflist()], dict:dict(log_id(), disk_log:log()), cache_id(), vectorclock()) -> {dict:dict(log_id(), disk_log:log()), vectorclock()} | {error, reason()}. +-spec open_logs(string(), [preflist()], dict:dict(log_id(), disklog()), cache_id(), vectorclock()) -> {dict:dict(log_id(), disklog()), vectorclock()} | {error, reason()}. open_logs(_LogFile, [], Map, _ClockTable, MaxVector) -> {Map, MaxVector}; open_logs(LogFile, [Next|Rest], Map, ClockTable, MaxVector)-> @@ -924,7 +926,7 @@ open_logs(LogFile, [Next|Rest], Map, ClockTable, MaxVector)-> %% LogId: identifies the log. %% Return: The actual name of the log %% --spec get_log_from_map(dict:dict(log_id(), disk_log:log()), partition(), log_id()) -> +-spec get_log_from_map(dict:dict(log_id(), disklog()), partition(), log_id()) -> {ok, log()} | {error, no_log_for_preflist}. get_log_from_map(Map, _Partition, LogId) -> case dict:find(LogId, Map) of diff --git a/src/materializer_vnode.erl b/src/materializer_vnode.erl index 3ae4a1e83..7f807a84f 100644 --- a/src/materializer_vnode.erl +++ b/src/materializer_vnode.erl @@ -452,7 +452,7 @@ update_snapshot_from_cache(SnapshotResponse, Key, OpsCache) -> %% %% Will also return how many operations were in the cache. %% --spec fetch_updates_from_cache(cache_id(), key()) -> {[op_and_id()] | tuple(), integer()}. +-spec fetch_updates_from_cache(cache_id(), key()) -> {[op_and_id()] | tuple(), non_neg_integer()}. fetch_updates_from_cache(OpsCache, Key) -> case ets:lookup(OpsCache, Key) of [] -> diff --git a/src/meta_data_sender.erl b/src/meta_data_sender.erl index 51d3a3ad0..ece531d20 100644 --- a/src/meta_data_sender.erl +++ b/src/meta_data_sender.erl @@ -217,7 +217,7 @@ update(Name, MetaData, Entries, AddFun, RemoveFun, Initial) -> {AccNew, Acc2New} end, {maps:new(), MetaData}, Entries), %% Remove entries that no longer exist - maps:map(fun(NodeId, _Val) -> ok = RemoveFun(Name, NodeId) end, NodeErase), + _ = maps:map(fun(NodeId, _Val) -> ok = RemoveFun(Name, NodeId) end, NodeErase), NewMetaData. %% @private diff --git a/src/stable_meta_data_server.erl b/src/stable_meta_data_server.erl index f2a0ad6e6..49ecdf02b 100644 --- a/src/stable_meta_data_server.erl +++ b/src/stable_meta_data_server.erl @@ -150,16 +150,17 @@ init([]) -> _ -> false end, - case LoadFromDisk of + UpdatedTable = case LoadFromDisk of true -> - Table = dets:to_ets(DetsTable, Table), - logger:info("Loaded meta data from disk"); + TableFromDets = dets:to_ets(DetsTable, Table), + logger:info("Loaded meta data from disk"), + TableFromDets; false -> ok = dets:delete_all_objects(DetsTable), Table end, ok = dets:sync(DetsTable), - {ok, #state{table = Table, dets_table = DetsTable}}. + {ok, #state{table = UpdatedTable, dets_table = DetsTable}}. handle_cast(_Info, State) -> {noreply, State}. diff --git a/src/wait_init.erl b/src/wait_init.erl index aca319603..94002113a 100644 --- a/src/wait_init.erl +++ b/src/wait_init.erl @@ -39,7 +39,7 @@ %% and readitem gen_servers have been started. %% Returns true if all vnodes are initialized for all physical nodes, %% false otherwise --spec check_ready_nodes([node()]) -> true. +-spec check_ready_nodes([node()]) -> boolean(). check_ready_nodes(Nodes) -> lists:all(fun check_ready/1, Nodes).