From 0896038dd6be9faf94f1770d2f98e9bbac0479f3 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Mon, 19 Feb 2024 20:32:56 +0100 Subject: [PATCH] make writing safe (by using a tmp file and moving to actual location) --- src/fragment_store/fragment_store.cpp | 32 ++++++++++++++++--- src/fragment_store/message_fragment_store.cpp | 4 +-- src/fragment_store/message_fragment_store.hpp | 3 ++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/fragment_store/fragment_store.cpp b/src/fragment_store/fragment_store.cpp index a32573ac..932c0796 100644 --- a/src/fragment_store/fragment_store.cpp +++ b/src/fragment_store/fragment_store.cpp @@ -186,15 +186,17 @@ FragmentID FragmentStore::newFragmentFile( _reg.emplace(new_frag, mft); - throwEventConstruct(new_frag); - // meta needs to be synced to file std::function empty_data_cb = [](const uint8_t*, uint64_t) -> uint64_t { return 0; }; if (!syncToStorage(new_frag, empty_data_cb)) { + std::cerr << "FS error: syncToStorage failed while creating new fragment file\n"; _reg.destroy(new_frag); return entt::null; } + // while new metadata might be created here, making sure the file could be created is more important + throwEventConstruct(new_frag); + return new_frag; } FragmentID FragmentStore::newFragmentFile( @@ -266,12 +268,15 @@ bool FragmentStore::syncToStorage(FragmentID fid, std::function(fid).path + ".meta" + metaFileTypeSuffix(meta_type) + ".tmp"; + meta_tmp_path.replace_filename("." + meta_tmp_path.filename().generic_u8string()); std::ofstream meta_file{ - _reg.get(fid).path + ".meta" + metaFileTypeSuffix(meta_type), + meta_tmp_path, std::ios::out | std::ios::trunc | std::ios::binary // always binary, also for text }; if (!meta_file.is_open()) { + std::cerr << "FS error: failed to create temporary meta file\n"; return false; } @@ -280,12 +285,17 @@ bool FragmentStore::syncToStorage(FragmentID fid, std::function(fid).comp; } + std::filesystem::path data_tmp_path = _reg.get(fid).path + ".tmp"; + data_tmp_path.replace_filename("." + data_tmp_path.filename().generic_u8string()); std::ofstream data_file{ - _reg.get(fid).path, + data_tmp_path, std::ios::out | std::ios::trunc | std::ios::binary // always binary, also for text }; if (!data_file.is_open()) { + meta_file.close(); + std::filesystem::remove(meta_tmp_path); + std::cerr << "FS error: failed to create temporary data file\n"; return false; } @@ -419,9 +429,21 @@ bool FragmentStore::syncToStorage(FragmentID fid, std::function(fid).path + ".meta" + metaFileTypeSuffix(meta_type) + ); + + std::filesystem::rename( + data_tmp_path, + _reg.get(fid).path + ); + + // TODO: check return value of renames if (_reg.all_of(fid)) { _reg.remove(fid); diff --git a/src/fragment_store/message_fragment_store.cpp b/src/fragment_store/message_fragment_store.cpp index a39fc7d1..b4b4186e 100644 --- a/src/fragment_store/message_fragment_store.cpp +++ b/src/fragment_store/message_fragment_store.cpp @@ -105,8 +105,8 @@ void MessageFragmentStore::handleMessage(const Message3Handle& m) { if (fragment_uid.empty()) { for (auto& [ts_begin, ts_end, fid] : fuid_open) { const int64_t frag_range = int64_t(ts_end) - int64_t(ts_begin); - //constexpr static int64_t max_frag_ts_extent {1000*60*60}; - constexpr static int64_t max_frag_ts_extent {1000*60*3}; // 3min for testing + constexpr static int64_t max_frag_ts_extent {1000*60*60}; + //constexpr static int64_t max_frag_ts_extent {1000*60*3}; // 3min for testing const int64_t possible_extention = max_frag_ts_extent - frag_range; // which direction diff --git a/src/fragment_store/message_fragment_store.hpp b/src/fragment_store/message_fragment_store.hpp index b61fe9a5..363b32e0 100644 --- a/src/fragment_store/message_fragment_store.hpp +++ b/src/fragment_store/message_fragment_store.hpp @@ -36,6 +36,9 @@ namespace Fragment::Components { struct MessagesContact { std::vector id; }; + + // TODO: add src contact (self id) + } // Fragment::Components // handles fragments for messages