diff --git a/src/ra_server.erl b/src/ra_server.erl index 5f1bdef1..719a263b 100644 --- a/src/ra_server.erl +++ b/src/ra_server.erl @@ -1856,9 +1856,7 @@ handle_receive_snapshot(#pre_vote_rpc{} = PreVote, State) -> process_pre_vote(receive_snapshot, PreVote, State); handle_receive_snapshot(Msg, State) -> log_unhandled_msg(receive_snapshot, Msg, State), - %% drop all other events?? - %% TODO: work out what else to handle - {receive_snapshot, State, [{reply, {error, {unsupported_call, Msg}}}]}. + {receive_snapshot, State, []}. abort_receive(#{snapshot_phase := _Phase, last_applied := LastApplied, diff --git a/src/ra_server_proc.erl b/src/ra_server_proc.erl index a683c19c..d091ae16 100644 --- a/src/ra_server_proc.erl +++ b/src/ra_server_proc.erl @@ -1011,6 +1011,27 @@ receive_snapshot(info, {'DOWN', MRef, process, _Pid, _Info}, [log_id(State)]), receive_snapshot(info, receive_snapshot_timeout, State#state{leader_monitor = undefined}); +receive_snapshot(_, {command, Priority, {_CmdType, Data, noreply}}, + State) -> + %% forward to leader + case leader_id(State) of + undefined -> + ?WARN("~ts: receive_snapshot leader cast - leader not known. " + "Command is dropped.", [log_id(State)]), + {keep_state, State, []}; + LeaderId -> + ?DEBUG("~ts: receive_snapshot leader cast - redirecting to ~tw ", + [log_id(State), LeaderId]), + ok = ra:pipeline_command(LeaderId, Data, no_correlation, Priority), + {keep_state, State, []} + end; +receive_snapshot(cast, {command, _Priority, + {_CmdType, _Data, {notify, Corr, Pid}}}, + State) -> + _ = reject_command(Pid, Corr, State), + {keep_state, State, []}; +receive_snapshot({call, From}, ping, State) -> + {keep_state, State, [{reply, From, {pong, receive_snapshot}}]}; receive_snapshot(EventType, Msg, State00) -> %% HACK: if the EventType is a {call, From} we stash the from in the %% ServerState, this is so ra_server can defer the snapshot reply in diff --git a/test/ra_server_SUITE.erl b/test/ra_server_SUITE.erl index d0ce1c6c..c5e5cebe 100644 --- a/test/ra_server_SUITE.erl +++ b/test/ra_server_SUITE.erl @@ -80,6 +80,7 @@ all() -> receive_snapshot_request_vote_higher_term, receive_snapshot_request_vote_lower_term, receive_snapshot_pre_vote, + receive_snapshot_catchall_drops_unknown, snapshotted_follower_received_append_entries, leader_received_append_entries_reply_with_stale_last_index, leader_receives_install_snapshot_result, @@ -2870,6 +2871,16 @@ receive_snapshot_pre_vote(_Config) -> end, Effects)), ok. +receive_snapshot_catchall_drops_unknown(_Config) -> + %% Verify that the catch-all clause in handle_receive_snapshot + %% drops unknown messages without returning a permanent error + State = base_state(3, ?FUNCTION_NAME), + {receive_snapshot, State, []} = + ra_server:handle_receive_snapshot(some_unknown_message, State), + {receive_snapshot, State, []} = + ra_server:handle_receive_snapshot({weird, tuple, msg}, State), + ok. + snapshotted_follower_received_append_entries(_Config) -> N1 = ?N1, N2 = ?N2, N3 = ?N3, #{N3 := {_, FState00 = #{cluster := Config}, _}} = @@ -3544,13 +3555,13 @@ receive_snapshot_heartbeat_dropped(_Config) -> Heartbeat = #heartbeat_rpc{term = Term, query_index = QueryIndex, leader_id = Id}, - {receive_snapshot, State, [{reply, {error, {unsupported_call, _}}}]} = + {receive_snapshot, State, []} = ra_server:handle_receive_snapshot(Heartbeat, State), %% Term does not matter - {receive_snapshot, State, [{reply, {error, {unsupported_call, _}}}]} = + {receive_snapshot, State, []} = ra_server:handle_receive_snapshot(Heartbeat#heartbeat_rpc{term = Term + 1}, State), - {receive_snapshot, State, [{reply, {error, {unsupported_call, _}}}]} = + {receive_snapshot, State, []} = ra_server:handle_receive_snapshot(Heartbeat#heartbeat_rpc{term = Term - 1}, State). @@ -3561,13 +3572,13 @@ receive_snapshot_heartbeat_reply_dropped(_config) -> HeartbeatReply = #heartbeat_reply{term = Term, query_index = QueryIndex}, - {receive_snapshot, State, [{reply, {error, {unsupported_call, _}}}]} = + {receive_snapshot, State, []} = ra_server:handle_receive_snapshot(HeartbeatReply, State), %% Term does not matter - {receive_snapshot, State, [{reply, {error, {unsupported_call, _}}}]} = + {receive_snapshot, State, []} = ra_server:handle_receive_snapshot(HeartbeatReply#heartbeat_reply{term = Term + 1}, State), - {receive_snapshot, State, [{reply, {error, {unsupported_call, _}}}]} = + {receive_snapshot, State, []} = ra_server:handle_receive_snapshot(HeartbeatReply#heartbeat_reply{term = Term - 1}, State).