diff --git a/service/strong_consistency/groups_manager.cc b/service/strong_consistency/groups_manager.cc index e8330fdf11..0499668530 100644 --- a/service/strong_consistency/groups_manager.cc +++ b/service/strong_consistency/groups_manager.cc @@ -227,18 +227,9 @@ void groups_manager::schedule_raft_groups_deletion(bool all) { } future<> groups_manager::wait_for_groups_to_start(lowres_clock::time_point timeout) { - while (true) { - const auto it = std::ranges::find_if(_raft_groups, [](const auto& p) { - auto& state = p.second; - return !state.gate->is_closed() && !state.server_control_op.available(); - }); - if (it == _raft_groups.end()) { - break; - } - - const auto& [id, state] = *it; - logger.info("waiting for group {} to start", id); - co_await state.server_control_op.get_future(timeout); + while (!_starting_groups.empty()) { + auto& state = _starting_groups.front(); + co_await state.server_control_op.get_future(timeout); // the state is unlinked when this completes } } @@ -388,11 +379,13 @@ void groups_manager::update(token_metadata_ptr new_tm) { logger.info("update(): starting raft server for tablet {}, group id {}", tablet, id); state.gate = make_lw_shared(); + _starting_groups.push_back(state); state.server_control_op = futurize_invoke([&state, this, tablet, id, new_tm](this auto) -> future<> { co_await state.server_control_op.get_future(); co_await start_raft_group(tablet, id, std::move(new_tm)); state.server = &_raft_gr.get_server(id); state.leader_info_updater = leader_info_updater(state, tablet, id); + _starting_groups.erase(_starting_groups.iterator_to(state)); logger.info("update(): raft server for tablet {} and group id {} is started", tablet, id); }); }); diff --git a/service/strong_consistency/groups_manager.hh b/service/strong_consistency/groups_manager.hh index 9f4a8e3c27..49b5e485f9 100644 --- a/service/strong_consistency/groups_manager.hh +++ b/service/strong_consistency/groups_manager.hh @@ -57,7 +57,7 @@ class groups_manager : public peering_sharded_service { api::timestamp_type last_timestamp; }; - struct raft_group_state { + struct raft_group_state : public boost::intrusive::list_base_hook> { bool has_tablet = false; lw_shared_ptr gate = nullptr; raft::server* server = nullptr; @@ -84,6 +84,7 @@ class groups_manager : public peering_sharded_service { gms::feature_service& _features; gms::gossiper& _gossiper; std::unordered_map _raft_groups = {}; + boost::intrusive::list> _starting_groups; locator::token_metadata_ptr _pending_tm = nullptr; bool _started = false;