diff --git a/service/raft/discovery.cc b/service/raft/discovery.cc index 6dd0faf0bd..312acae8f0 100644 --- a/service/raft/discovery.cc +++ b/service/raft/discovery.cc @@ -93,8 +93,11 @@ void discovery::maybe_become_leader() { } } -discovery::peer_list discovery::request(const peer_list& peers) { +std::optional discovery::request(const peer_list& peers) { step(peers); + if (_is_leader) { + return std::nullopt; + } return _peer_list; } diff --git a/service/raft/discovery.hh b/service/raft/discovery.hh index 59cc3eb497..ef5efdba12 100644 --- a/service/raft/discovery.hh +++ b/service/raft/discovery.hh @@ -86,10 +86,10 @@ public: discovery(raft::server_address self, const peer_list& seeds); // To be used on the receiving peer to generate a reply - // while the discovery protocol is in progress. Always - // returns a peer list, even if this node is a leader, - // since leader state must be persisted first. - peer_list request(const peer_list& peers); + // while the discovery protocol is in progress. + // Until the node becomes a leader, returns the list of known peers. + // When (if) the node becomes a leader, returns std::nullopt. + std::optional request(const peer_list& peers); // Submit a reply from one of the peers to this discovery // state machine. If this node is a leader, resposne is diff --git a/service/raft/raft_group0.cc b/service/raft/raft_group0.cc index 750d28374e..47e4686594 100644 --- a/service/raft/raft_group0.cc +++ b/service/raft/raft_group0.cc @@ -299,7 +299,12 @@ future raft_group0::peer_exchange(discovery::peer_list pee co_return group0_peer_exchange{std::monostate{}}; } else if constexpr (std::is_same_v) { // Use discovery to produce a response - co_return group0_peer_exchange{d.request(std::move(peers))}; + if (auto response = d.request(std::move(peers))) { + co_return group0_peer_exchange{std::move(*response)}; + } + // We just became a leader. + // Eventually we'll answer with group0_info. + co_return group0_peer_exchange{std::monostate{}}; } else if constexpr (std::is_same_v) { // Even if in follower state, return own address: the // incoming RPC will then be bounced to the leader. diff --git a/test/raft/discovery_test.cc b/test/raft/discovery_test.cc index 31d4cce50e..f9ff12b94c 100644 --- a/test/raft/discovery_test.cc +++ b/test/raft/discovery_test.cc @@ -34,7 +34,9 @@ run_discovery_impl(discovery_network& network) { continue; } discovery& to = *(it->second); - from.response(m.first, to.request(m.second)); + if (auto peer_list = to.request(m.second)) { + from.response(m.first, std::move(*peer_list)); + } } } }