Use atomic file for rtsim data

This commit is contained in:
Joshua Barretto 2023-04-03 21:27:16 +01:00
parent 082bcdb755
commit 2e047f6723

View File

@ -2,6 +2,7 @@ pub mod event;
pub mod rule; pub mod rule;
pub mod tick; pub mod tick;
use atomicwrites::{AtomicFile, OverwriteBehavior};
use common::{ use common::{
grid::Grid, grid::Grid,
rtsim::{ChunkResource, RtSimEntity, RtSimVehicle, WorldSettings}, rtsim::{ChunkResource, RtSimEntity, RtSimVehicle, WorldSettings},
@ -18,7 +19,7 @@ use specs::DispatcherBuilder;
use std::{ use std::{
error::Error, error::Error,
fs::{self, File}, fs::{self, File},
io::{self, Write}, io,
path::PathBuf, path::PathBuf,
time::Instant, time::Instant,
}; };
@ -182,23 +183,24 @@ impl RtSim {
// TODO: Use slow job // TODO: Use slow job
// slowjob_pool.spawn("RTSIM_SAVE", move || { // slowjob_pool.spawn("RTSIM_SAVE", move || {
let handle = std::thread::spawn(move || { let handle = std::thread::spawn(move || {
let tmp_file_name = "data_tmp.dat";
if let Err(e) = file_path if let Err(e) = file_path
.parent() .parent()
.map(|dir| { .map(|dir| {
fs::create_dir_all(dir)?; fs::create_dir_all(dir)?;
// We write to a temporary file and then rename to avoid corruption. // We write to a temporary file and then rename to avoid corruption.
Ok(dir.join(tmp_file_name)) Ok(dir.join(&file_path))
}) })
.unwrap_or_else(|| Ok(tmp_file_name.into())) .unwrap_or(Ok(file_path))
.and_then(|tmp_file_path| Ok((File::create(&tmp_file_path)?, tmp_file_path))) .map(|file_path| AtomicFile::new(file_path, OverwriteBehavior::AllowOverwrite))
.map_err(|e: io::Error| Box::new(e) as Box<dyn Error>) .map_err(|e: io::Error| Box::new(e) as Box<dyn Error>)
.and_then(|(mut file, tmp_file_path)| { .and_then(|file| {
debug!("Writing rtsim data to file..."); debug!("Writing rtsim data to file...");
data.write_to(io::BufWriter::new(&mut file))?; file.write(move |file| -> Result<(), rtsim::data::WriteError> {
file.flush()?; data.write_to(io::BufWriter::new(file))?;
// file.flush()?;
Ok(())
})?;
drop(file); drop(file);
fs::rename(tmp_file_path, file_path)?;
debug!("Rtsim data saved."); debug!("Rtsim data saved.");
Ok(()) Ok(())
}) })