|
24 | 24 | #include "fetch_data_rpc_generated.h" |
25 | 25 | #include <nuraft_mesg/common.hpp> |
26 | 26 |
|
| 27 | +#include <boost/uuid/string_generator.hpp> |
| 28 | + |
27 | 29 | namespace homestore { |
28 | 30 | std::atomic< uint64_t > RaftReplDev::s_next_group_ordinal{1}; |
29 | 31 |
|
@@ -1853,16 +1855,50 @@ void RaftReplDev::clean_replace_member_task(repl_req_ptr_t rreq) { |
1853 | 1855 | auto task_id = std::string(r_cast< const char* >(rreq->header().cbytes())); |
1854 | 1856 | RD_LOGI(rreq->traceID(), "Raft repl clean_replace_member_task commit, task_id={}", task_id); |
1855 | 1857 |
|
1856 | | - std::unique_lock lg{m_sb_mtx}; |
1857 | | - auto persisted_task_id = get_replace_member_task_id(); |
1858 | | - if (!persisted_task_id.empty()) { |
1859 | | - RD_DBG_ASSERT(persisted_task_id == task_id, |
1860 | | - "Invalid task_id in clean_replace_member_task message, received {}, persisted {}", task_id, |
1861 | | - persisted_task_id); |
1862 | | - m_rd_sb->replace_member_task = replace_member_task_superblk{}; |
1863 | | - m_rd_sb.write(); |
| 1858 | + replica_member_info member_out; |
| 1859 | + replica_member_info member_in; |
| 1860 | + |
| 1861 | + // Step 1: Check and read member info from superblk |
| 1862 | + { |
| 1863 | + std::unique_lock lg{m_sb_mtx}; |
| 1864 | + auto persisted_task_id = get_replace_member_task_id(); |
| 1865 | + if (persisted_task_id.empty()) { |
| 1866 | + RD_LOGI(rreq->traceID(), "Raft repl clean_replace_member_task: task not found, task_id={}", task_id); |
| 1867 | + return; |
| 1868 | + } |
| 1869 | + |
| 1870 | + if (persisted_task_id != task_id) { |
| 1871 | + RD_LOGW(rreq->traceID(), |
| 1872 | + "Raft repl clean_replace_member_task: task_id mismatch, received={}, persisted={}, skip cleaning", |
| 1873 | + task_id, persisted_task_id); |
| 1874 | + return; |
| 1875 | + } |
| 1876 | + |
| 1877 | + // Read member info from superblk |
| 1878 | + member_out.id = m_rd_sb->replace_member_task.replica_out; |
| 1879 | + member_in.id = m_rd_sb->replace_member_task.replica_in; |
| 1880 | + } |
| 1881 | + |
| 1882 | + // Step 2: Call listener callback to rollback membership in HomeObject |
| 1883 | + if (member_out.id != boost::uuids::nil_uuid() && member_in.id != boost::uuids::nil_uuid()) { |
| 1884 | + RD_LOGI(rreq->traceID(), |
| 1885 | + "Raft repl clean_replace_member_task, callback to listener, task_id={}, member_out={}, member_in={}", |
| 1886 | + task_id, boost::uuids::to_string(member_out.id), boost::uuids::to_string(member_in.id)); |
| 1887 | + m_listener->on_clean_replace_member_task(task_id, member_out, member_in, rreq->traceID()); |
| 1888 | + } else { |
| 1889 | + RD_LOGW(rreq->traceID(), "Raft repl clean_replace_member_task: invalid member info, skip callback"); |
| 1890 | + } |
| 1891 | + |
| 1892 | + // Step 3: Clear the replace_member task from superblk |
| 1893 | + { |
| 1894 | + std::unique_lock lg{m_sb_mtx}; |
| 1895 | + auto persisted_task_id = get_replace_member_task_id(); |
| 1896 | + if (!persisted_task_id.empty()) { |
| 1897 | + m_rd_sb->replace_member_task = replace_member_task_superblk{}; |
| 1898 | + m_rd_sb.write(); |
| 1899 | + RD_LOGI(rreq->traceID(), "Raft repl replace_member_task has been cleared, task_id={}", task_id); |
| 1900 | + } |
1864 | 1901 | } |
1865 | | - RD_LOGI(rreq->traceID(), "Raft repl replace_member_task has been cleared, task_id={}", task_id); |
1866 | 1902 | } |
1867 | 1903 |
|
1868 | 1904 | void RaftReplDev::update_truncation_boundary(repl_lsn_t truncation_upper_limit) { |
@@ -1980,6 +2016,24 @@ std::vector< peer_info > RaftReplDev::get_replication_status() const { |
1980 | 2016 | return pi; |
1981 | 2017 | } |
1982 | 2018 |
|
| 2019 | +std::vector< replica_id_t > RaftReplDev::get_replication_quorum() { |
| 2020 | + std::vector< replica_id_t > member_ids; |
| 2021 | + auto msg_service = group_msg_service(); |
| 2022 | + |
| 2023 | + if (msg_service) { |
| 2024 | + std::list< nuraft_mesg::replica_config > cluster_config; |
| 2025 | + msg_service->get_cluster_config(cluster_config); |
| 2026 | + for (auto const& config : cluster_config) { |
| 2027 | + member_ids.push_back(boost::uuids::string_generator()(config.peer_id)); |
| 2028 | + } |
| 2029 | + RD_LOGD(NO_TRACE_ID, "get_replication_quorum: found {} members in cluster config", member_ids.size()); |
| 2030 | + } else { |
| 2031 | + RD_LOGW(NO_TRACE_ID, "get_replication_quorum: msg_service is null, returning empty member list"); |
| 2032 | + } |
| 2033 | + |
| 2034 | + return member_ids; |
| 2035 | +} |
| 2036 | + |
1983 | 2037 | void RaftReplDev::reconcile_leader() { |
1984 | 2038 | int32_t my_priority = raft_server()->get_srv_config(m_raft_server_id)->get_priority(); |
1985 | 2039 | if (!is_leader()) { |
|
0 commit comments