From 21f05cf8eecca73f51ff86ce3f86729042b7ecc6 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Tue, 31 Oct 2023 09:18:44 -0400 Subject: [PATCH] ra_server: Add a comment explaining the promotion target index The worry here about `ra_log:next_index/1` is that the peer joining might be 'stuck' if this were off-by-one: if the cluster weren't handling any other new commands other than the `$ra_join`, the peer would be able to catch up to `ra_log`'s `LastIndex` but not this target, so the peer wouldn't be promotable until the cluster handled some other command. This isn't the case though because the next index is immediately used for a cluster change command which updates this peer's promotion target. So it should be possible for the peer to reach its promotion target even if the cluster doesn't handle any other commands by the time the candidate catches up to the target. This change just documents why the next index is ok to use. --- src/ra_server.erl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ra_server.erl b/src/ra_server.erl index 405b44d9..406728ac 100644 --- a/src/ra_server.erl +++ b/src/ra_server.erl @@ -2907,6 +2907,10 @@ ensure_promotion_target(#{membership := promotable, target := _, uid := _} = Sta {ok, Status}; ensure_promotion_target(#{membership := promotable, uid := _} = Status, #{log := Log}) -> + %% The next index in the log is used by for a cluster change command: + %% the caller of `ensure_promotion_target/2' also calls + %% `append_cluster_change/4'. So even if a peer joins a cluster which isn't + %% handling any other commands, this promotion target will be reachable. Target = ra_log:next_index(Log), {ok, Status#{target => Target}}; ensure_promotion_target(#{membership := promotable}, _) ->