From 412718da88f2851c7b1cf9594e790f7607b31f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=80=9D=E6=97=A0=E9=82=AA?= <65906820+578223592@users.noreply.github.com> Date: Sun, 7 Apr 2024 12:49:45 +0800 Subject: [PATCH] =?UTF-8?q?bugfix=EF=BC=9Apersist=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/raftCore/Persister.cpp | 79 ++++++++++++++++++++++++-------- src/raftCore/include/Persister.h | 30 ++++++++++-- 2 files changed, 85 insertions(+), 24 deletions(-) diff --git a/src/raftCore/Persister.cpp b/src/raftCore/Persister.cpp index 3ece02a..c38a20a 100644 --- a/src/raftCore/Persister.cpp +++ b/src/raftCore/Persister.cpp @@ -3,25 +3,26 @@ // #include "Persister.h" #include "util.h" -// todo:如果文件出现问题会怎么办?? + +// todo:会涉及反复打开文件的操作,没有考虑如果文件出现问题会怎么办?? void Persister::Save(const std::string raftstate, const std::string snapshot) { - std::lock_guard lg(mtx); + std::lock_guard lg(m_mtx); + clearRaftStateAndSnapshot(); // 将raftstate和snapshot写入本地文件 - std::ofstream outfile; m_raftStateOutStream << raftstate; m_snapshotOutStream << snapshot; } std::string Persister::ReadSnapshot() { - std::lock_guard lg(mtx); + std::lock_guard lg(m_mtx); if (m_snapshotOutStream.is_open()) { m_snapshotOutStream.close(); } - // Defer ec1([this]()-> void { - // this->m_snapshotOutStream.open(snapshotFile); - // }); //这个变量后生成,会先销毁 - DEFER { m_snapshotOutStream.open(snapshotFile); }; //这个变量后生成,会先销毁 - std::fstream ifs(snapshotFile, std::ios_base::in); + + DEFER { + m_snapshotOutStream.open(m_snapshotFileName); //默认是追加 + }; + std::fstream ifs(m_snapshotFileName, std::ios_base::in); if (!ifs.good()) { return ""; } @@ -32,21 +33,23 @@ std::string Persister::ReadSnapshot() { } void Persister::SaveRaftState(const std::string &data) { - std::lock_guard lg(mtx); + std::lock_guard lg(m_mtx); // 将raftstate和snapshot写入本地文件 + clearRaftState(); m_raftStateOutStream << data; + m_raftStateSize += data.size(); } long long Persister::RaftStateSize() { - std::lock_guard lg(mtx); + std::lock_guard lg(m_mtx); return m_raftStateSize; } std::string Persister::ReadRaftState() { - std::lock_guard lg(mtx); + std::lock_guard lg(m_mtx); - std::fstream ifs(raftStateFile, std::ios_base::in); + std::fstream ifs(m_raftStateFileName, std::ios_base::in); if (!ifs.good()) { return ""; } @@ -56,20 +59,34 @@ std::string Persister::ReadRaftState() { return snapshot; } -Persister::Persister(int me) - : raftStateFile("raftstatePersist" + std::to_string(me) + ".txt"), - snapshotFile("snapshotPersist" + std::to_string(me) + ".txt"), +Persister::Persister(const int me) + : m_raftStateFileName("raftstatePersist" + std::to_string(me) + ".txt"), + m_snapshotFileName("snapshotPersist" + std::to_string(me) + ".txt"), m_raftStateSize(0) { - std::fstream file(raftStateFile, std::ios::out | std::ios::trunc); + /** + * 检查文件状态并清空文件 + */ + bool fileOpenFlag = true; + std::fstream file(m_raftStateFileName, std::ios::out | std::ios::trunc); if (file.is_open()) { file.close(); + } else { + fileOpenFlag = false; } - file = std::fstream(snapshotFile, std::ios::out | std::ios::trunc); + file = std::fstream(m_snapshotFileName, std::ios::out | std::ios::trunc); if (file.is_open()) { file.close(); + } else { + fileOpenFlag = false; } - m_raftStateOutStream.open(raftStateFile); - m_snapshotOutStream.open(snapshotFile); + if (!fileOpenFlag) { + DPrintf("[func-Persister::Persister] file open error"); + } + /** + * 绑定流 + */ + m_raftStateOutStream.open(m_raftStateFileName); + m_snapshotOutStream.open(m_snapshotFileName); } Persister::~Persister() { @@ -80,3 +97,25 @@ Persister::~Persister() { m_snapshotOutStream.close(); } } + +void Persister::clearRaftState() { + m_raftStateSize = 0; + // 关闭文件流 + if (m_raftStateOutStream.is_open()) { + m_raftStateOutStream.close(); + } + // 重新打开文件流并清空文件内容 + m_raftStateOutStream.open(m_raftStateFileName, std::ios::out | std::ios::trunc); +} + +void Persister::clearSnapshot() { + if (m_snapshotOutStream.is_open()) { + m_snapshotOutStream.close(); + } + m_snapshotOutStream.open(m_snapshotFileName, std::ios::out | std::ios::trunc); +} + +void Persister::clearRaftStateAndSnapshot() { + clearRaftState(); + clearSnapshot(); +} diff --git a/src/raftCore/include/Persister.h b/src/raftCore/include/Persister.h index 695f9b9..38d80f8 100644 --- a/src/raftCore/include/Persister.h +++ b/src/raftCore/include/Persister.h @@ -8,14 +8,31 @@ #include class Persister { private: - std::mutex mtx; + std::mutex m_mtx; std::string m_raftState; std::string m_snapshot; - const std::string raftStateFile; - const std::string snapshotFile; + /** + * m_raftStateFileName: raftState文件名 + */ + const std::string m_raftStateFileName; + /** + * m_snapshotFileName: snapshot文件名 + */ + const std::string m_snapshotFileName; + /** + * 保存raftState的输出流 + */ std::ofstream m_raftStateOutStream; + /** + * 保存snapshot的输出流 + */ std::ofstream m_snapshotOutStream; - long long m_raftStateSize; //避免每次都读取文件的具体大小 + /** + * 保存raftStateSize的大小 + * 避免每次都读取文件来获取具体的大小 + */ + long long m_raftStateSize; + public: void Save(std::string raftstate, std::string snapshot); std::string ReadSnapshot(); @@ -24,6 +41,11 @@ class Persister { std::string ReadRaftState(); explicit Persister(int me); ~Persister(); + + private: + void clearRaftState(); + void clearSnapshot(); + void clearRaftStateAndSnapshot(); }; #endif // SKIP_LIST_ON_RAFT_PERSISTER_H