diff --git a/.gitignore b/.gitignore index b69da15ed..522974903 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,7 @@ _build rebar.lock .DS_Store nonode@nohost +data/* +test/*.beam +log/* +core_vnode_eqc.log diff --git a/.travis.yml b/.travis.yml index dc4a56526..28739038e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: erlang otp_release: - 20.3.8 + - 21.3 + - 22.3 script: - chmod u+x rebar3 - ./rebar3 do upgrade, compile, dialyzer, xref, eunit diff --git a/Makefile b/Makefile index 60edb9118..96875a9f2 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: compile rel cover test dialyzer +.PHONY: compile rel cover test dialyzer eqc REBAR=./rebar3 compile: @@ -7,11 +7,12 @@ compile: clean: $(REBAR) clean -cover: test +cover: + $(REBAR) eunit --cover $(REBAR) cover test: compile - $(REBAR) as test do eunit + $(REBAR) eunit dialyzer: $(REBAR) dialyzer @@ -19,4 +20,8 @@ dialyzer: xref: $(REBAR) xref +eqc: + $(REBAR) as test eqc --testing_budget 120 + $(REBAR) as eqc eunit + check: test dialyzer xref diff --git a/eqc/bg_manager_eqc.erl b/eqc/bg_manager_eqc.erl index c148b6e69..b158ba794 100644 --- a/eqc/bg_manager_eqc.erl +++ b/eqc/bg_manager_eqc.erl @@ -19,7 +19,6 @@ -module(bg_manager_eqc). --ifdef(TEST). -ifdef(EQC). -include("include/riak_core_bg_manager.hrl"). @@ -858,4 +857,3 @@ prop_bgmgr_parallel() -> end))). -endif. --endif. diff --git a/eqc/worker_pool_pulse.erl b/eqc/worker_pool_pulse.erl index 95a5cbe62..e67053157 100644 --- a/eqc/worker_pool_pulse.erl +++ b/eqc/worker_pool_pulse.erl @@ -59,7 +59,7 @@ handle_work(Work, _From, State) -> %% @doc Any amount of work should complete through any size pool. prop_any_pool() -> - ?SETUP(fun setup_and_teardown/1, + ?SETUP(fun setup_and_teardown/0, ?FORALL({Seed, ExtraWork, WorkList}, {pulse:seed(), frequency([{10,true},{1,false}]), diff --git a/rebar.config b/rebar.config index 09e649429..3f31122c0 100644 --- a/rebar.config +++ b/rebar.config @@ -1,36 +1,40 @@ {erl_first_files, ["src/gen_nb_server.erl", "src/riak_core_gen_server.erl", "src/riak_core_stat_xform"]}. + {cover_enabled, true}. + {erl_opts, [warnings_as_errors, {parse_transform, lager_transform}, debug_info, {platform_define, "^[0-9]+", namespaced_types}, {platform_define, "^R15", "old_hash"}, - {platform_define, "^[2-9][1-9][0-9]*(.?[0-9]*)", deprecated_21}]}. + {platform_define, "^[2-9][1-9][0-9]*(.?[0-9]*)", deprecated_21}, + {platform_define, "^[2-9][2-9][0-9]*(.?[0-9]*)", deprecated_22}]}. + {edoc_opts, [{preprocess, true}]}. + {eunit_opts, [verbose]}. -{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used, - deprecated_function_calls, deprecated_functions]}. -{plugins, [{rebar3_eqc, {git, "https://github.com/Vagabond/rebar3-eqc-plugin", {branch, "master"}}}]}. +{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used]}. + +{plugins, [{eqc_rebar, {git, "https://github.com/Quviq/eqc-rebar", {branch, "master"}}}]}. {deps, [ {lager, {git, "git://github.com/erlang-lager/lager.git", {tag, "3.8.0"}}}, {poolboy, {git, "https://github.com/basho/poolboy.git", {tag, "riak_kv-3.0.0"}}}, - {basho_stats, {git, "git://github.com/basho/basho_stats.git", {tag, "1.1.0"}}}, {riak_sysmon, {git, "git://github.com/basho/riak_sysmon.git", {tag, "2.2.0"}}}, {clique, {git, "git://github.com/basho/clique.git", {tag, "0.3.11"}}}, - gen_fsm_compat, {eleveldb, {git, "git://github.com/basho/eleveldb.git", {tag, "riak_kv-3.0.0"}}}, {riak_ensemble, {git, "https://github.com/basho/riak_ensemble", {tag, "riak_kv-3.0.0"}}}, {pbkdf2, {git, "git://github.com/basho/erlang-pbkdf2.git", {tag, "2.1.0"}}}, {cluster_info, {git, "git://github.com/basho/cluster_info.git", {tag, "2.1.0"}}}, - {exometer_core, {git, "git://github.com/Feuerlabs/exometer_core.git", {tag, "v1.5.7"}}} + {exometer_core, {git, "git://github.com/Feuerlabs/exometer_core.git", {tag, "v1.5.7"}}}, + {basho_stats, {git, "git://github.com/basho/basho_stats.git", {tag, "1.1.0"}}} ]}. {dialyzer, [{plt_apps, all_deps}]}. {profiles, [ {test, [{deps, [meck]}, {erl_opts, [nowarn_export_all]}]}, - {eqc, [{deps, [meck]}, {erl_opts, [nowarn_export_all]}]} + {eqc, [{deps, [meck]}, {erl_opts, [{d, 'EQC'}, nowarn_export_all]}]} ]}. diff --git a/rebar3 b/rebar3 index f0b1ba788..e550663ab 100755 Binary files a/rebar3 and b/rebar3 differ diff --git a/src/hashtree.erl b/src/hashtree.erl index 8dc3f0a91..846ac3bea 100644 --- a/src/hashtree.erl +++ b/src/hashtree.erl @@ -154,16 +154,14 @@ run_multiple/2, run_remote/0, run_remote/1]). --endif. % TEST -ifdef(EQC). -export([prop_correct/0, prop_sha/0, prop_est/0]). -include_lib("eqc/include/eqc.hrl"). -endif. --ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). --endif. +-endif. %% TEST -define(NUM_SEGMENTS, (1024*1024)). -define(WIDTH, 1024). @@ -1167,7 +1165,7 @@ compare(Level, Bucket, Tree, Remote, AccFun, KeyAcc) -> Inter = ordsets:intersection(ordsets:from_list(HL1), ordsets:from_list(HL2)), Diff = ordsets:subtract(Union, Inter), - lager:debug("Tree ~p level ~p bucket ~p\nL=~p\nR=~p\nD=\n", + lager:debug("Tree ~p level ~p bucket ~p\nL=~p\nR=~p\nD=~p\n", [Tree, Level, Bucket, HL1, HL2, Diff]), KeyAcc3 = lists:foldl(fun({Bucket2, _}, KeyAcc2) -> @@ -1584,6 +1582,7 @@ opened_closed_test() -> %%% EQC %%%=================================================================== +-ifdef(TEST). -ifdef(EQC). prop_sha() -> %% NOTE: Generating 1MB (1024 * 1024) size binaries is incredibly slow @@ -1692,3 +1691,4 @@ prop_est() -> true end). -endif. +-endif. diff --git a/src/riak_core.app.src b/src/riak_core.app.src index 7a2ad6401..75e0a177c 100644 --- a/src/riak_core.app.src +++ b/src/riak_core.app.src @@ -16,14 +16,13 @@ tools, riak_sysmon, os_mon, - basho_stats, eleveldb, pbkdf2, poolboy, exometer_core, clique, cluster_info, - gen_fsm_compat + basho_stats ]}, {mod, {riak_core_app, []}}, {env, [ diff --git a/src/riak_core_claim.erl b/src/riak_core_claim.erl index 9661f9d4a..e40247c0d 100644 --- a/src/riak_core_claim.erl +++ b/src/riak_core_claim.erl @@ -70,7 +70,7 @@ -compile(export_all). -ifdef(EQC). -export([prop_claim_ensures_unique_nodes/1, prop_wants/0, prop_wants_counts/0,eqc_check/2, - prop_claim_ensures_unique_nodes_v2/0, prop_claim_ensures_unique_nodes_v3/0, + prop_claim_ensures_unique_nodes_v2/0, % prop_claim_ensures_unique_nodes_v3/0, prop_take_idxs/0]). -include_lib("eqc/include/eqc.hrl"). -endif. @@ -1364,15 +1364,27 @@ claim_ensures_unique_nodes_adding_singly_v2_test_() -> {timeout, 120, fun() -> ?assert(eqc:quickcheck(Prop)) end}. %% Run few tests in eunit and more if needed by calling "./rebar3 eqc" -claim_ensures_unique_nodes_v3_test_() -> - Prop = eqc:numtests(5, ?QC_OUT(prop_claim_ensures_unique_nodes_old(choose_claim_v3))), - {timeout, 240, fun() -> ?assert(eqc:quickcheck(Prop)) end}. +% claim_ensures_unique_nodes_v3_test_() -> +% Prop = eqc:numtests(5, ?QC_OUT(prop_claim_ensures_unique_nodes_old(choose_claim_v3))), +% {timeout, 240, fun() -> ?assert(eqc:quickcheck(Prop)) end}. prop_claim_ensures_unique_nodes_v2() -> prop_claim_ensures_unique_nodes(choose_claim_v2). -prop_claim_ensures_unique_nodes_v3() -> - prop_claim_ensures_unique_nodes(choose_claim_v3). +%% No longer test properties of claim_v3. +%% Although claim_v3 continues to exist as a hidden configuration option, it +%% is known to fail to meet the required properties, and claim_v2 should be +%% used in all known circumstances. +%% +%% TODO : Remove claim_v3 from the code base +%% +%% This TODO is currently deferred due to the difficulty of understanding +%% how to test the full possibility of cluster change scenarios. Perhaps +%% there may be circumstances where a probabilistic approach to planning +%% cluster changes may still be beneficial +%% +% prop_claim_ensures_unique_nodes_v3() -> +% prop_claim_ensures_unique_nodes(choose_claim_v3). %% NOTE: this is a less than adequate test that has been re-instated %% so that we don't leave the code worse than we found it. Work that diff --git a/src/riak_core_claim_sim.erl b/src/riak_core_claim_sim.erl index 07219d629..3ef57e790 100644 --- a/src/riak_core_claim_sim.erl +++ b/src/riak_core_claim_sim.erl @@ -554,7 +554,8 @@ run_test() -> {analysis, [{failures, 2},{n_val, 3}]}, {print,Fh}, {return_ring, false}])), - file:close(Fh). + file:close(Fh), + file:delete("sim.out"). %% Decided not to run by default, perhaps better as an diff --git a/src/riak_core_coverage_fsm.erl b/src/riak_core_coverage_fsm.erl index 742fc78e3..394531815 100644 --- a/src/riak_core_coverage_fsm.erl +++ b/src/riak_core_coverage_fsm.erl @@ -64,7 +64,11 @@ -include("riak_core_vnode.hrl"). --behaviour(gen_fsm_compat). +-behaviour(gen_fsm). + +-compile({nowarn_deprecated_function, + [{gen_fsm, start_link, 3}, + {gen_fsm, start_timer, 2}]}). -export([start_link/3]). @@ -74,7 +78,7 @@ -export([test_link/5]). -endif. -%% gen_fsm_compat callbacks +%% gen_fsm callbacks -export([init/1, initialize/2, waiting_results/2, @@ -142,7 +146,7 @@ -spec start_link(module(), from(), [term()]) -> {ok, pid()} | ignore | {error, term()}. start_link(Mod, From, RequestArgs) -> - gen_fsm_compat:start_link(?MODULE, [Mod, From, RequestArgs], []). + gen_fsm:start_link(?MODULE, [Mod, From, RequestArgs], []). %% =================================================================== %% Test API @@ -153,7 +157,7 @@ start_link(Mod, From, RequestArgs) -> %% Create a coverage FSM for testing. test_link(Mod, From, RequestArgs, _Options, StateProps) -> Timeout = 60000, - gen_fsm_compat:start_link(?MODULE, + gen_fsm:start_link(?MODULE, {test, [Mod, From, @@ -165,7 +169,7 @@ test_link(Mod, From, RequestArgs, _Options, StateProps) -> -endif. %% ==================================================================== -%% gen_fsm_compat callbacks +%% gen_fsm callbacks %% ==================================================================== %% @private @@ -214,7 +218,7 @@ maybe_start_timeout_timer(infinity) -> maybe_start_timeout_timer(Bad) when not is_integer(Bad) -> maybe_start_timeout_timer(?DEFAULT_TIMEOUT); maybe_start_timeout_timer(Timeout) -> - gen_fsm_compat:start_timer(Timeout, {timer_expired, Timeout}), + gen_fsm:start_timer(Timeout, {timer_expired, Timeout}), ok. diff --git a/src/riak_core_gen_server.erl b/src/riak_core_gen_server.erl index b73289616..ecbd4af78 100644 --- a/src/riak_core_gen_server.erl +++ b/src/riak_core_gen_server.erl @@ -182,7 +182,7 @@ %%% Preprocessor %%%========================================================================= --ifdef(deprecated_21). +-ifdef(deprecated_22). get_log(Debug) -> sys:get_log(Debug). -else. diff --git a/src/riak_core_handoff_receiver.erl b/src/riak_core_handoff_receiver.erl index 66881032a..8caa3d17b 100644 --- a/src/riak_core_handoff_receiver.erl +++ b/src/riak_core_handoff_receiver.erl @@ -23,6 +23,10 @@ -module(riak_core_handoff_receiver). -include("riak_core_handoff.hrl"). -behaviour(riak_core_gen_server). + +-compile({nowarn_deprecated_function, + [{gen_fsm, sync_send_all_state_event, 3}]}). + -export([start_link/0, % Don't use SSL start_link/1, % SSL options list, empty=no SSL set_socket/2, @@ -141,7 +145,7 @@ process_message(?PT_MSG_BATCH, MsgData, State) -> process_message(?PT_MSG_OBJ, MsgData, State=#state{vnode=VNode, count=Count, vnode_timeout_len=VNodeTimeout}) -> Msg = {handoff_data, MsgData}, - try gen_fsm_compat:sync_send_all_state_event(VNode, Msg, VNodeTimeout) of + try gen_fsm:sync_send_all_state_event(VNode, Msg, VNodeTimeout) of ok -> State#state{count=Count+1}; E={error, _} -> diff --git a/src/riak_core_handoff_sender.erl b/src/riak_core_handoff_sender.erl index 260a22532..9de02c9e0 100644 --- a/src/riak_core_handoff_sender.erl +++ b/src/riak_core_handoff_sender.erl @@ -22,6 +22,10 @@ -module(riak_core_handoff_sender). -export([start_link/4, get_handoff_ssl_options/0]). + +-compile({nowarn_deprecated_function, + [{gen_fsm, send_event, 2}]}). + -include("riak_core_vnode.hrl"). -include("riak_core_handoff.hrl"). -include("stacktrace.hrl"). @@ -252,9 +256,9 @@ start_fold(TargetNode, Module, {Type, Opts}, ParentPid, SslOpts) -> riak_core_format:human_size_fmt("~.2f", ThroughputBytes)]), case Type of repair -> ok; - resize -> gen_fsm_compat:send_event(ParentPid, {resize_transfer_complete, + resize -> gen_fsm:send_event(ParentPid, {resize_transfer_complete, NotSentAcc}); - _ -> gen_fsm_compat:send_event(ParentPid, handoff_complete) + _ -> gen_fsm:send_event(ParentPid, handoff_complete) end; {error, ErrReason} -> if ErrReason == timeout -> @@ -274,15 +278,15 @@ start_fold(TargetNode, Module, {Type, Opts}, ParentPid, SslOpts) -> exit({shutdown, timeout}); exit:{shutdown, {error, Reason}} -> ?log_fail("because of ~p", [Reason]), - gen_fsm_compat:send_event(ParentPid, {handoff_error, + gen_fsm:send_event(ParentPid, {handoff_error, fold_error, Reason}), exit({shutdown, {error, Reason}}); throw:{be_quiet, Err, Reason} -> - gen_fsm_compat:send_event(ParentPid, {handoff_error, Err, Reason}); + gen_fsm:send_event(ParentPid, {handoff_error, Err, Reason}); ?_exception_(Err, Reason, StackToken) -> ?log_fail("because of ~p:~p ~p", [Err, Reason, ?_get_stacktrace_(StackToken)]), - gen_fsm_compat:send_event(ParentPid, {handoff_error, Err, Reason}) + gen_fsm:send_event(ParentPid, {handoff_error, Err, Reason}) end. start_visit_item_timer() -> diff --git a/src/riak_core_metadata_exchange_fsm.erl b/src/riak_core_metadata_exchange_fsm.erl index b56c59696..e35ff00a7 100644 --- a/src/riak_core_metadata_exchange_fsm.erl +++ b/src/riak_core_metadata_exchange_fsm.erl @@ -19,16 +19,20 @@ %% ------------------------------------------------------------------- -module(riak_core_metadata_exchange_fsm). --behaviour(gen_fsm_compat). +-behaviour(gen_fsm). + +-compile({nowarn_deprecated_function, + [{gen_fsm, start, 3}, + {gen_fsm, send_event, 2}]}). %% API -export([start/2]). -%% gen_fsm_compat callbacks +%% gen_fsm callbacks -export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -%% gen_fsm_compat states +%% gen_fsm states -export([prepare/2, prepare/3, update/2, @@ -71,14 +75,14 @@ %% to aqcuire the remote lock or to upate both trees. -spec start(node(), pos_integer()) -> {ok, pid()} | ignore | {error, term()}. start(Peer, Timeout) -> - gen_fsm_compat:start(?MODULE, [Peer, Timeout], []). + gen_fsm:start(?MODULE, [Peer, Timeout], []). %%%=================================================================== -%%% gen_fsm_compat callbacks +%%% gen_fsm callbacks %%%=================================================================== init([Peer, Timeout]) -> - gen_fsm_compat:send_event(self(), start), + gen_fsm:send_event(self(), start), {ok, prepare, #state{peer=Peer,built=0,timeout=Timeout}}. handle_event(_Event, StateName, State) -> @@ -98,7 +102,7 @@ code_change(_OldVsn, StateName, State, _Extra) -> {ok, StateName, State}. %%%=================================================================== -%%% gen_fsm_compat states +%%% gen_fsm states %%%=================================================================== prepare(start, State) -> %% get local lock @@ -296,6 +300,6 @@ as_event(F) -> Self = self(), spawn_link(fun() -> Result = F(), - gen_fsm_compat:send_event(Self, Result) + gen_fsm:send_event(Self, Result) end), ok. diff --git a/src/riak_core_ring_manager.erl b/src/riak_core_ring_manager.erl index cd280e530..e12ec49ae 100644 --- a/src/riak_core_ring_manager.erl +++ b/src/riak_core_ring_manager.erl @@ -242,6 +242,7 @@ do_write_ringfile(Ring) -> do_write_ringfile(Ring, FN) -> ok = filelib:ensure_dir(FN), try + false = riak_core_ring:check_lastgasp(Ring), ok = riak_core_util:replace_file(FN, term_to_binary(Ring)) catch _:Err -> @@ -274,8 +275,11 @@ find_latest_ringfile() -> read_ringfile(RingFile) -> case file:read_file(RingFile) of {ok, Binary} -> - binary_to_term(Binary); - {error, Reason} -> {error, Reason} + R = binary_to_term(Binary), + false = riak_core_ring:check_lastgasp(R), + R; + {error, Reason} -> + {error, Reason} end. %% @spec prune_ringfiles() -> ok | {error, Reason} @@ -748,7 +752,9 @@ do_write_ringfile_test() -> %% Check rename fails ok = file:change_mode(?TEST_RINGDIR, 8#00444), ?assertMatch({error,_}, do_write_ringfile(GenR(ring_perms), ?TEST_RINGFILE)), - ok = file:change_mode(?TEST_RINGDIR, 8#00755). + ok = file:change_mode(?TEST_RINGDIR, 8#00755), + ok = file:change_mode(?TEST_RINGFILE, 8#00644), + ok = file:delete(?TEST_RINGFILE). is_stable_ring_test() -> {A,B,C} = Now = os:timestamp(), diff --git a/src/riak_core_ssl_util.erl b/src/riak_core_ssl_util.erl index 735d0191e..b85d6f80c 100644 --- a/src/riak_core_ssl_util.erl +++ b/src/riak_core_ssl_util.erl @@ -48,6 +48,24 @@ ssl_handshake(Socket, SslOpts) -> ssl:ssl_accept(Socket, SslOpts). -endif. +-ifdef(deprecated_21). + -ifdef(deprecated_22). + openssl_suite(Cipher) -> + ssl_cipher_format:suite_openssl_str_to_map(Cipher). + openssl_suite_name(Cipher) -> + ssl_cipher_format:suite_map_to_openssl_str(ssl_cipher_format:suite_bin_to_map(Cipher)). + -else. + openssl_suite(Cipher) -> + ssl_cipher_format:openssl_suite(Cipher). + openssl_suite_name(Cipher) -> + ssl_cipher_format:openssl_suite_name(Cipher). + -endif. +-else. +openssl_suite(Cipher) -> + ssl_cipher:openssl_suite(Cipher). +openssl_suite_name(Cipher) -> + ssl_cipher:openssl_suite_name(Cipher). +-endif. maybe_use_ssl(App) -> SSLOpts = [ @@ -321,7 +339,7 @@ posix_error(Error) -> %% suites. parse_ciphers(CipherList) -> {Good, Bad} = lists:foldl(fun(Cipher, {Acc, Unknown}) -> - try ssl_cipher:openssl_suite(Cipher) of + try openssl_suite(Cipher) of C -> {[C|Acc], Unknown} catch @@ -335,7 +353,7 @@ parse_ciphers(CipherList) -> %% print the OpenSSL name for ciphers print_ciphers(CipherList) -> - string:join([ssl_cipher:openssl_suite_name(Cipher) || Cipher <- + string:join([openssl_suite_name(Cipher) || Cipher <- CipherList], ":"). diff --git a/src/riak_core_stat.erl b/src/riak_core_stat.erl index 8f00ad32e..7506cd17b 100644 --- a/src/riak_core_stat.erl +++ b/src/riak_core_stat.erl @@ -20,6 +20,11 @@ -module(riak_core_stat). +%% There is a dialyzer issue within exometer_core, as a temporary solution +%% there will be no warnings from these specific functions +%% - https://github.com/basho/riak_core/issues/946 +-dialyzer({nowarn_function, register_vnode_stats/3}). + -behaviour(gen_server). %% API diff --git a/src/riak_core_vnode.erl b/src/riak_core_vnode.erl index 859df81d3..83f88e813 100644 --- a/src/riak_core_vnode.erl +++ b/src/riak_core_vnode.erl @@ -17,7 +17,17 @@ %% %% ------------------------------------------------------------------- -module('riak_core_vnode'). --behaviour(gen_fsm_compat). +-behaviour(gen_fsm). + +-compile({nowarn_deprecated_function, + [{gen_fsm, start_link, 3}, + {gen_fsm, send_event, 2}, + {gen_fsm, send_event_after, 2}, + {gen_fsm, sync_send_event, 3}, + {gen_fsm, send_all_state_event, 2}, + {gen_fsm, sync_send_all_state_event, 2}, + {gen_fsm, cancel_timer, 1}]}). + -include("riak_core_vnode.hrl"). -export([start_link/3, start_link/4, @@ -59,7 +69,7 @@ -ifdef(PULSE). -compile(export_all). -compile({parse_transform, pulse_instrument}). --compile({pulse_replace_module, [{gen_fsm_compat, pulse_gen_fsm}, +-compile({pulse_replace_module, [{gen_fsm, pulse_gen_fsm}, {gen_server, pulse_gen_server}]}). -endif. @@ -134,7 +144,7 @@ %% message and the function signature is: handle_exit(Pid, Reason, State). %% %% It should return a tuple indicating the next state for the fsm. For a list of -%% valid return types see the documentation for the gen_fsm_compat handle_info callback. +%% valid return types see the documentation for the gen_fsm handle_info callback. %% %% Here is what the spec for handle_exit/3 would look like: %% -spec handle_exit(pid(), atom(), term()) -> @@ -170,20 +180,20 @@ start_link(Mod, Index, Forward) -> start_link(Mod, Index, 0, Forward). start_link(Mod, Index, InitialInactivityTimeout, Forward) -> - gen_fsm_compat:start_link(?MODULE, + gen_fsm:start_link(?MODULE, [Mod, Index, InitialInactivityTimeout, Forward], []). %% Send a command message for the vnode module by Pid - %% typically to do some deferred processing after returning yourself send_command(Pid, Request) -> - gen_fsm_compat:send_event(Pid, ?VNODE_REQ{request=Request}). + gen_fsm:send_event(Pid, ?VNODE_REQ{request=Request}). %% Sends a command to the FSM that called it after Time %% has passed. -spec send_command_after(integer(), term()) -> reference(). send_command_after(Time, Request) -> - gen_fsm_compat:send_event_after(Time, ?VNODE_REQ{request=Request}). + gen_fsm:send_event_after(Time, ?VNODE_REQ{request=Request}). init([Mod, Index, InitialInactivityTimeout, Forward]) -> @@ -269,28 +279,28 @@ do_init(State = #state{index=Index, mod=Mod, forward=Forward}) -> end. wait_for_init(Vnode) -> - gen_fsm_compat:sync_send_event(Vnode, wait_for_init, infinity). + gen_fsm:sync_send_event(Vnode, wait_for_init, infinity). handoff_error(Vnode, Err, Reason) -> - gen_fsm_compat:send_event(Vnode, {handoff_error, Err, Reason}). + gen_fsm:send_event(Vnode, {handoff_error, Err, Reason}). get_mod_index(VNode) -> - gen_fsm_compat:sync_send_all_state_event(VNode, get_mod_index). + gen_fsm:sync_send_all_state_event(VNode, get_mod_index). set_forwarding(VNode, ForwardTo) -> - gen_fsm_compat:send_all_state_event(VNode, {set_forwarding, ForwardTo}). + gen_fsm:send_all_state_event(VNode, {set_forwarding, ForwardTo}). trigger_handoff(VNode, TargetIdx, TargetNode) -> - gen_fsm_compat:send_all_state_event(VNode, {trigger_handoff, TargetIdx, TargetNode}). + gen_fsm:send_all_state_event(VNode, {trigger_handoff, TargetIdx, TargetNode}). trigger_handoff(VNode, TargetNode) -> - gen_fsm_compat:send_all_state_event(VNode, {trigger_handoff, TargetNode}). + gen_fsm:send_all_state_event(VNode, {trigger_handoff, TargetNode}). trigger_delete(VNode) -> - gen_fsm_compat:send_all_state_event(VNode, trigger_delete). + gen_fsm:send_all_state_event(VNode, trigger_delete). core_status(VNode) -> - gen_fsm_compat:sync_send_all_state_event(VNode, core_status). + gen_fsm:sync_send_all_state_event(VNode, core_status). continue(State) -> {next_state, active, State, State#state.inactivity_timeout}. @@ -1061,13 +1071,13 @@ monitor(ignore) -> start_manager_event_timer(Event, State=#state{mod=Mod, index=Idx}) -> riak_core_vnode_manager:vnode_event(Mod, Idx, self(), Event), stop_manager_event_timer(State), - T2 = gen_fsm_compat:send_event_after(30000, {send_manager_event, Event}), + T2 = gen_fsm:send_event_after(30000, {send_manager_event, Event}), State#state{manager_event_timer=T2}. stop_manager_event_timer(#state{manager_event_timer=undefined}) -> ok; stop_manager_event_timer(#state{manager_event_timer=T}) -> - _ = gen_fsm_compat:cancel_timer(T), + _ = gen_fsm:cancel_timer(T), ok. is_request_forwardable(#riak_core_fold_req_v2{forwardable=false}) -> @@ -1114,19 +1124,19 @@ queue_work(PoolName, Work, From, VnodeWrkPool) -> %% @doc Reveal the underlying module state for testing -spec(get_modstate(pid()) -> {atom(), #state{}}). get_modstate(Pid) -> - {_StateName, State} = gen_fsm_compat:sync_send_all_state_event(Pid, current_state), + {_StateName, State} = gen_fsm:sync_send_all_state_event(Pid, current_state), {State#state.mod, State#state.modstate}. -ifdef(TEST). %% Start the garbage collection server test_link(Mod, Index) -> - gen_fsm_compat:start_link(?MODULE, [Mod, Index, 0, node()], []). + gen_fsm:start_link(?MODULE, [Mod, Index, 0, node()], []). %% Get the current state of the fsm for testing inspection -spec current_state(pid()) -> {atom(), #state{}} | {error, term()}. current_state(Pid) -> - gen_fsm_compat:sync_send_all_state_event(Pid, current_state). + gen_fsm:sync_send_all_state_event(Pid, current_state). pool_death_test_() -> {timeout, 60, [ diff --git a/src/riak_core_vnode_manager.erl b/src/riak_core_vnode_manager.erl index 723f0a134..d2c0874b0 100644 --- a/src/riak_core_vnode_manager.erl +++ b/src/riak_core_vnode_manager.erl @@ -22,6 +22,14 @@ -module(riak_core_vnode_manager). +%% There is a dialyzer issue within exometer_core, as a temporary solution +%% there will be no warnings from these specific functions +%% - https://github.com/basho/riak_core/issues/946 +-dialyzer({nowarn_function, [get_vnode/3, register_vnode_stats/3]}). + +-compile({nowarn_deprecated_function, + [{gen_fsm, send_all_state_event, 2}]}). + -behaviour(gen_server). -export([start_link/0, stop/0]). @@ -472,11 +480,11 @@ handle_vnode_event(inactive, Mod, Idx, Pid, State) -> {noreply, State}; handle_vnode_event(handoff_complete, Mod, Idx, Pid, State) -> NewHO = dict:erase({Mod, Idx}, State#state.handoff), - gen_fsm_compat:send_all_state_event(Pid, finish_handoff), + gen_fsm:send_all_state_event(Pid, finish_handoff), {noreply, State#state{handoff=NewHO}}; handle_vnode_event(handoff_error, Mod, Idx, Pid, State) -> NewHO = dict:erase({Mod, Idx}, State#state.handoff), - gen_fsm_compat:send_all_state_event(Pid, cancel_handoff), + gen_fsm:send_all_state_event(Pid, cancel_handoff), {noreply, State#state{handoff=NewHO}}. %% @private diff --git a/src/riak_core_vnode_master.erl b/src/riak_core_vnode_master.erl index 8ccdf65c6..88912917a 100644 --- a/src/riak_core_vnode_master.erl +++ b/src/riak_core_vnode_master.erl @@ -25,6 +25,11 @@ -module(riak_core_vnode_master). -include("riak_core_vnode.hrl"). -behaviour(gen_server). + +-compile({nowarn_deprecated_function, + [{gen_fsm, send_event, 2}, + {gen_fsm, send_all_state_event, 2}]}). + -export([start_link/1, start_link/2, start_link/3, get_vnode_pid/2, start_vnode/2, command/3, command/4, @@ -83,7 +88,7 @@ command2([], _Msg, _Sender, _VMaster, _How) -> command2([{Index, Pid}|Rest], Msg, Sender, VMaster, How=normal) when is_pid(Pid) -> - gen_fsm_compat:send_event(Pid, make_request(Msg, Sender, Index)), + gen_fsm:send_event(Pid, make_request(Msg, Sender, Index)), command2(Rest, Msg, Sender, VMaster, How); command2([{Index, Pid}|Rest], Msg, Sender, VMaster, How=unreliable) @@ -213,7 +218,7 @@ do_proxy_cast({VMaster, Node}, Req=?COVERAGE_REQ{index=Idx}, How) -> ok. send_an_event(Dest, Event, normal) -> - gen_fsm_compat:send_event(Dest, Event); + gen_fsm:send_event(Dest, Event); send_an_event(Dest, Event, unreliable) -> riak_core_send_msg:send_event_unreliable(Dest, Event). @@ -228,11 +233,11 @@ handle_cast({wait_for_service, Service}, State) -> {noreply, State}; handle_cast(Req=?VNODE_REQ{index=Idx}, State=#state{vnode_mod=Mod}) -> Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx), - gen_fsm_compat:send_event(Proxy, Req), + gen_fsm:send_event(Proxy, Req), {noreply, State}; handle_cast(Req=?COVERAGE_REQ{index=Idx}, State=#state{vnode_mod=Mod}) -> Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx), - gen_fsm_compat:send_event(Proxy, Req), + gen_fsm:send_event(Proxy, Req), {noreply, State}; handle_cast(Other, State=#state{legacy=Legacy}) when Legacy =/= undefined -> case catch Legacy:rewrite_cast(Other) of @@ -250,7 +255,7 @@ handle_call({return_vnode, Req=?VNODE_REQ{index=Idx}}, _From, handle_call(Req=?VNODE_REQ{index=Idx, sender={server, undefined, undefined}}, From, State=#state{vnode_mod=Mod}) -> Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx), - gen_fsm_compat:send_event(Proxy, Req?VNODE_REQ{sender={server, undefined, From}}), + gen_fsm:send_event(Proxy, Req?VNODE_REQ{sender={server, undefined, From}}), {noreply, State}; handle_call({spawn, Req=?VNODE_REQ{index=Idx, sender={server, undefined, undefined}}}, @@ -258,7 +263,7 @@ handle_call({spawn, Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx), Sender = {server, undefined, From}, spawn_link( - fun() -> gen_fsm_compat:send_all_state_event(Proxy, Req?VNODE_REQ{sender=Sender}) end), + fun() -> gen_fsm:send_all_state_event(Proxy, Req?VNODE_REQ{sender=Sender}) end), {noreply, State}; handle_call(Other, From, State=#state{legacy=Legacy}) when Legacy =/= undefined -> case catch Legacy:rewrite_call(Other, From) of diff --git a/src/riak_core_vnode_proxy.erl b/src/riak_core_vnode_proxy.erl index 84d2893f1..dfd907a3e 100644 --- a/src/riak_core_vnode_proxy.erl +++ b/src/riak_core_vnode_proxy.erl @@ -23,6 +23,9 @@ -export([soft_load_mailbox_check/2]). -include("riak_core_vnode.hrl"). +-compile({nowarn_deprecated_function, + [{gen_fsm, send_event, 2}]}). + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). -endif. @@ -161,7 +164,7 @@ loop(Parent, State) -> %% @private handle_call({return_vnode, Req}, _From, State) -> {Pid, NewState} = get_vnode_pid(State), - gen_fsm_compat:send_event(Pid, Req), + gen_fsm:send_event(Pid, Req), {reply, {ok, Pid}, NewState}; handle_call(overloaded, _From, State=#state{check_mailbox=Mailbox, check_threshold=Threshold}) -> @@ -178,7 +181,7 @@ handle_call(_Msg, _From, State) -> handle_cast({unregister_vnode, Pid}, State) -> %% The pid may not match the vnode_pid in the state, but we must send the %% unregister event anyway -- the vnode manager requires it. - gen_fsm_compat:send_event(Pid, unregistered), + gen_fsm:send_event(Pid, unregistered), catch demonitor(State#state.vnode_mref, [flush]), NewState = forget_vnode(State), {noreply, NewState}; diff --git a/src/riak_core_vnode_worker.erl b/src/riak_core_vnode_worker.erl index 7504be53b..72d2026a5 100644 --- a/src/riak_core_vnode_worker.erl +++ b/src/riak_core_vnode_worker.erl @@ -20,6 +20,9 @@ -behaviour(gen_server). +-compile({nowarn_deprecated_function, + [{gen_fsm, send_all_state_event, 2}]}). + -include("riak_core_vnode.hrl"). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, @@ -29,7 +32,7 @@ -ifdef(PULSE). -compile(export_all). -compile({parse_transform, pulse_instrument}). --compile({pulse_replace_module, [{gen_fsm_compat, pulse_gen_fsm}, +-compile({pulse_replace_module, [{gen_fsm, pulse_gen_fsm}, {gen_server, pulse_gen_server}]}). -endif. @@ -63,7 +66,7 @@ handle_work(Worker, Work, From, Caller) -> init([Module, VNodeIndex, WorkerArgs, WorkerProps, Caller]) -> {ok, WorkerState} = Module:init_worker(VNodeIndex, WorkerArgs, WorkerProps), %% let the pool queue manager know there might be a worker to checkout - gen_fsm_compat:send_all_state_event(Caller, worker_start), + gen_fsm:send_all_state_event(Caller, worker_start), {ok, #state{module=Module, modstate=WorkerState}}. handle_call(Event, _From, State) -> @@ -80,7 +83,7 @@ handle_cast({work, Work, WorkFrom, Caller}, NS end, %% check the worker back into the pool - gen_fsm_compat:send_all_state_event(Caller, {checkin, self()}), + gen_fsm:send_all_state_event(Caller, {checkin, self()}), {noreply, State#state{modstate=NewModState}}; handle_cast(_Event, State) -> {noreply, State}. diff --git a/src/riak_core_worker_pool.erl b/src/riak_core_worker_pool.erl index 6757070cb..1b70bad75 100644 --- a/src/riak_core_worker_pool.erl +++ b/src/riak_core_worker_pool.erl @@ -39,15 +39,21 @@ %% confuse (or cause a race) with this module's checkout management. -module(riak_core_worker_pool). --behaviour(gen_fsm_compat). +-behaviour(gen_fsm). -%% gen_fsm_compat callbacks +-compile({nowarn_deprecated_function, + [{gen_fsm, start_link, 3}, + {gen_fsm, send_event, 2}, + {gen_fsm, sync_send_all_state_event, 2}, + {gen_fsm, sync_send_all_state_event, 3}]}). + +%% gen_fsm callbacks -export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -export([start_link/2, handle_work/3, stop/2, shutdown_pool/2]). -%% gen_fsm_compat states +%% gen_fsm states -export([queueing/2, ready/2, ready/3, queueing/3, shutdown/2, shutdown/3]). -export([monitor_worker/4]). @@ -55,7 +61,7 @@ -ifdef(PULSE). -compile(export_all). -compile({parse_transform, pulse_instrument}). --compile({pulse_replace_module, [{gen_fsm_compat, pulse_gen_fsm}]}). +-compile({pulse_replace_module, [{gen_fsm, pulse_gen_fsm}]}). -endif. -define(SHUTDOWN_WAIT, 60000). @@ -83,17 +89,17 @@ start_link(PoolBoyArgs, CallbackMod) -> - gen_fsm_compat:start_link(?MODULE, [PoolBoyArgs, CallbackMod], []). + gen_fsm:start_link(?MODULE, [PoolBoyArgs, CallbackMod], []). handle_work(Pid, Work, From) -> - gen_fsm_compat:send_event(Pid, {work, Work, From}). + gen_fsm:send_event(Pid, {work, Work, From}). stop(Pid, Reason) -> - gen_fsm_compat:sync_send_all_state_event(Pid, {stop, Reason}). + gen_fsm:sync_send_all_state_event(Pid, {stop, Reason}). %% wait for all the workers to finish any current work shutdown_pool(Pid, Wait) -> - gen_fsm_compat:sync_send_all_state_event(Pid, {shutdown, Wait}, infinity). + gen_fsm:sync_send_all_state_event(Pid, {shutdown, Wait}, infinity). init([PoolBoyArgs, CallbackMod]) -> {ok, Pid} = CallbackMod:do_init(PoolBoyArgs), @@ -173,8 +179,14 @@ handle_event(worker_start, StateName, #state{pool=Pool, queue=Q, monitors=Monito {next_state, queueing, State#state{queue=Rem, monitors=NewMonitors}} end; {empty, _} -> - %% StateName might be either 'ready' or 'shutdown' - {next_state, StateName, State} + {next_state, + %% If we are in state queueing with nothing in the queue, + %% move to the ready state so that the next incoming job + %% checks out the new worker from poolboy. + if StateName==queueing -> ready; + true -> StateName + end, + State} end; handle_event(_Event, StateName, State) -> {next_state, StateName, State}. @@ -242,10 +254,10 @@ handle_info(_Info, StateName, State) -> terminate(shutdown, _StateName, #state{pool=Pool, queue=Q, callback_mod=Mod}) -> discard_queued_work(Q, Mod), %% stop poolboy - gen_fsm_compat:sync_send_all_state_event(Pool, stop), + gen_fsm:sync_send_all_state_event(Pool, stop), ok; terminate(_Reason, _StateName, #state{pool=Pool}) -> - gen_fsm_compat:sync_send_all_state_event(Pool, stop), + gen_fsm:sync_send_all_state_event(Pool, stop), ok. code_change(_OldVsn, StateName, State, _Extra) -> diff --git a/test/riak_core_claim_statem.erl b/test/riak_core_claim_statem.erl index 6e9c84ee6..fd3b9f3c6 100644 --- a/test/riak_core_claim_statem.erl +++ b/test/riak_core_claim_statem.erl @@ -244,6 +244,9 @@ weight(_, _, _, _) -> -define(QC_OUT(P), eqc:on_output(fun(Str, Args) -> io:format(user, Str, Args) end, P)). +claim_test() -> + eqc:quickcheck(?QC_OUT(prop_claim(with_ring_size(5)))). + eqc_check(File, Prop) -> {ok, Bytes} = file:read_file(File), CE = binary_to_term(Bytes),