1616
1717#include < algorithm>
1818#include < chrono>
19+ #include < filesystem>
1920#include < memory>
2021#include < stdexcept>
2122#include < string>
@@ -44,6 +45,19 @@ std::string strip_parent_path(const std::string & relative_path)
4445{
4546 return rcpputils::fs::path (relative_path).filename ().string ();
4647}
48+
49+ std::string remove_active_from_filename (const std::string& relative_path)
50+ {
51+ rcpputils::fs::path path (relative_path);
52+ auto filename = path.filename ().string ();
53+ auto active_pos = filename.find (" .active" );
54+ if (active_pos != std::string::npos) {
55+ filename.replace (active_pos, 7 , " " );
56+ }
57+ auto new_path = path.parent_path () / filename;
58+ return new_path.string ();
59+ }
60+
4761} // namespace
4862
4963SequentialWriter::SequentialWriter (
@@ -173,7 +187,11 @@ void SequentialWriter::close()
173187 }
174188
175189 if (storage_) {
190+ // when the storage_ is closed, rename the file to remove ".active" suffix
191+ std::string active_path = storage_->get_relative_file_path ();
192+ std::string final_path = remove_active_from_filename (active_path);
176193 storage_.reset (); // Destroy storage before calling WRITE_SPLIT callback to make sure that
194+ std::filesystem::rename (active_path, final_path);
177195 // bag file was closed before callback call.
178196 }
179197 if (!metadata_.relative_file_paths .empty ()) {
@@ -257,7 +275,7 @@ std::string SequentialWriter::format_storage_uri(
257275 // The name of the folder needs to be queried in case
258276 // SequentialWriter is opened with a relative path.
259277 std::stringstream storage_file_name;
260- storage_file_name << rcpputils::fs::path (base_folder).filename ().string () << " _" << storage_count;
278+ storage_file_name << rcpputils::fs::path (base_folder).filename ().string () << " _" << storage_count << " .active " ;
261279
262280 return (rcpputils::fs::path (base_folder) / storage_file_name.str ()).string ();
263281}
@@ -269,11 +287,22 @@ void SequentialWriter::switch_to_next_storage()
269287 cache_consumer_->stop ();
270288 message_cache_->log_dropped ();
271289 }
290+ // Write the metadata before splitting. This will be replaced by an updated file later.
291+ // In this way, if the process crashes, the metadata for the previous parts will still be available.
292+ finalize_metadata ();
293+ metadata_io_->write_metadata (base_folder_, metadata_);
272294
273295 storage_options_.uri = format_storage_uri (
274296 base_folder_,
275297 metadata_.relative_file_paths .size ());
298+
299+ // when the storage_ is closed, rename the file to remove ".inactive" suffix
300+ std::string active_path = storage_->get_relative_file_path ();
301+ std::string final_path = remove_active_from_filename (active_path);
302+
276303 storage_ = storage_factory_->open_read_write (storage_options_);
304+
305+ std::filesystem::rename (active_path, final_path);
277306
278307 if (!storage_) {
279308 std::stringstream errmsg;
0 commit comments