16
16
17
17
#include < algorithm>
18
18
#include < chrono>
19
+ #include < filesystem>
19
20
#include < memory>
20
21
#include < stdexcept>
21
22
#include < string>
@@ -44,6 +45,19 @@ std::string strip_parent_path(const std::string & relative_path)
44
45
{
45
46
return rcpputils::fs::path (relative_path).filename ().string ();
46
47
}
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
+
47
61
} // namespace
48
62
49
63
SequentialWriter::SequentialWriter (
@@ -173,7 +187,11 @@ void SequentialWriter::close()
173
187
}
174
188
175
189
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);
176
193
storage_.reset (); // Destroy storage before calling WRITE_SPLIT callback to make sure that
194
+ std::filesystem::rename (active_path, final_path);
177
195
// bag file was closed before callback call.
178
196
}
179
197
if (!metadata_.relative_file_paths .empty ()) {
@@ -257,7 +275,7 @@ std::string SequentialWriter::format_storage_uri(
257
275
// The name of the folder needs to be queried in case
258
276
// SequentialWriter is opened with a relative path.
259
277
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 " ;
261
279
262
280
return (rcpputils::fs::path (base_folder) / storage_file_name.str ()).string ();
263
281
}
@@ -269,11 +287,22 @@ void SequentialWriter::switch_to_next_storage()
269
287
cache_consumer_->stop ();
270
288
message_cache_->log_dropped ();
271
289
}
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_);
272
294
273
295
storage_options_.uri = format_storage_uri (
274
296
base_folder_,
275
297
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
+
276
303
storage_ = storage_factory_->open_read_write (storage_options_);
304
+
305
+ std::filesystem::rename (active_path, final_path);
277
306
278
307
if (!storage_) {
279
308
std::stringstream errmsg;
0 commit comments