Skip to content

Commit 33bdbe0

Browse files
author
Alex Valiushko
committed
Newly added followers do not participate in quorum until they catch up with the log
1 parent 54860c4 commit 33bdbe0

File tree

9 files changed

+511
-43
lines changed

9 files changed

+511
-43
lines changed

src/ra.erl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ start_cluster(System, [#{cluster_name := ClusterName} | _] = ServerConfigs,
454454

455455
%% @doc Starts a new distributed ra cluster.
456456
%% @param ClusterName the name of the cluster.
457-
%% @param ServerId the ra_server_id() of the server
457+
%% @param ServerId the ra_server_id() of the server, or a map with server id and settings.
458458
%% @param Machine The {@link ra_machine:machine/0} configuration.
459459
%% @param ServerIds a list of initial (seed) server configurations
460460
%% @returns
@@ -469,17 +469,21 @@ start_cluster(System, [#{cluster_name := ClusterName} | _] = ServerConfigs,
469469
%% forcefully deleted.
470470
%% @see start_server/1
471471
%% @end
472-
-spec start_server(atom(), ra_cluster_name(), ra_server_id(),
472+
-spec start_server(atom(), ra_cluster_name(), ra_server_id() | ra_new_server(),
473473
ra_server:machine_conf(), [ra_server_id()]) ->
474474
ok | {error, term()}.
475-
start_server(System, ClusterName, {_, _} = ServerId, Machine, ServerIds)
475+
start_server(System, ClusterName, {_, _} = ServerId, Machine, ServerIds) ->
476+
% Legacy start server, default to full voter
477+
start_server(System, ClusterName, #{id => ServerId, voter => true}, Machine, ServerIds);
478+
start_server(System, ClusterName, #{id := {_, _} = ServerId, voter := Voter}, Machine, ServerIds)
476479
when is_atom(System) ->
477480
UId = new_uid(ra_lib:to_binary(ClusterName)),
478481
Conf = #{cluster_name => ClusterName,
479482
id => ServerId,
480483
uid => UId,
481484
initial_members => ServerIds,
482485
log_init_args => #{uid => UId},
486+
voter => Voter,
483487
machine => Machine},
484488
start_server(System, Conf).
485489

@@ -557,9 +561,10 @@ delete_cluster(ServerIds, Timeout) ->
557561
%% affect said cluster's availability characteristics (by increasing quorum node count).
558562
%%
559563
%% @param ServerLoc the ra server or servers to try to send the command to
560-
%% @param ServerId the ra server id of the new server.
564+
%% @param ServerId the ra server id of the new server, or a map with server id and settings.
561565
%% @end
562-
-spec add_member(ra_server_id() | [ra_server_id()], ra_server_id()) ->
566+
-spec add_member(ra_server_id() | [ra_server_id()],
567+
ra_server_id() | ra_new_server()) ->
563568
ra_cmd_ret() |
564569
{error, already_member} |
565570
{error, cluster_change_not_permitted}.
@@ -570,7 +575,8 @@ add_member(ServerLoc, ServerId) ->
570575
%% @see add_member/2
571576
%% @end
572577
-spec add_member(ra_server_id() | [ra_server_id()],
573-
ra_server_id(), timeout()) ->
578+
ra_server_id() | ra_new_server(),
579+
timeout()) ->
574580
ra_cmd_ret() |
575581
{error, already_member} |
576582
{error, cluster_change_not_permitted}.
@@ -579,7 +585,6 @@ add_member(ServerLoc, ServerId, Timeout) ->
579585
{'$ra_join', ServerId, after_log_append},
580586
Timeout).
581587

582-
583588
%% @doc Removes a server from the cluster's membership configuration.
584589
%% This function returns after appending a cluster membership change
585590
%% command to the log.

src/ra.hrl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,27 @@
3939
%% after node restart). Pids are not stable in this sense.
4040
-type ra_server_id() :: {Name :: atom(), Node :: node()}.
4141

42+
%% Specifies server configuration for a new cluster member.
43+
-type ra_new_server() :: #{id := ra_server_id(),
44+
voter := boolean()}.
45+
4246
-type ra_peer_status() :: normal |
4347
{sending_snapshot, pid()} |
4448
suspended |
4549
disconnected.
4650

51+
-type ra_voter_status() :: voter | {nonvoter, ra_nonvoter_reason()}.
52+
53+
-type ra_nonvoter_reason() :: init | #{target := ra_index()}.
54+
4755
-type ra_peer_state() :: #{next_index := non_neg_integer(),
4856
match_index := non_neg_integer(),
4957
query_index := non_neg_integer(),
5058
% the commit index last sent
5159
% used for evaluating pipeline status
5260
commit_index_sent := non_neg_integer(),
61+
%% whether the peer is part of the consensus
62+
voter_status := ra_voter_status(),
5363
%% indicates that a snapshot is being sent
5464
%% to the peer
5565
status := ra_peer_status()}.

src/ra_directory.erl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,20 @@ overview(System) when is_atom(System) ->
175175
#{directory := Tbl,
176176
directory_rev := _TblRev} = get_names(System),
177177
Dir = ets:tab2list(Tbl),
178-
States = maps:from_list(ets:tab2list(ra_state)),
178+
Rows = lists:map(fun({K, S, V}) ->
179+
{K, {S, V}}
180+
end,
181+
ets:tab2list(ra_state)),
182+
States = maps:from_list(Rows),
179183
Snaps = maps:from_list(ets:tab2list(ra_log_snapshot_state)),
180184
lists:foldl(fun ({UId, Pid, Parent, ServerName, ClusterName}, Acc) ->
185+
{S, V} = maps:get(ServerName, States, {undefined, undefined}),
181186
Acc#{ServerName =>
182187
#{uid => UId,
183188
pid => Pid,
184189
parent => Parent,
185-
state => maps:get(ServerName, States, undefined),
190+
state => S,
191+
voter_status => V,
186192
cluster_name => ClusterName,
187193
snapshot_state => maps:get(UId, Snaps,
188194
undefined)}}

0 commit comments

Comments
 (0)