Skip to content

Commit

Permalink
libsql: offline sync use atomic write for metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
LucioFranco committed Nov 20, 2024
1 parent 5e38c1d commit 4a8460f
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion libsql/src/sync.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
use std::path::Path;

use tokio::io::AsyncWriteExt as _;
use uuid::Uuid;

use crate::Result;

const METADATA_VERSION: u32 = 0;
Expand Down Expand Up @@ -109,7 +114,7 @@ impl SyncContext {
})
.unwrap();

tokio::fs::write(path, contents).await.unwrap();
atomic_write(path, &contents[..]).await.unwrap();

Ok(())
}
Expand Down Expand Up @@ -142,3 +147,27 @@ struct MetadataJson {
version: u32,
durable_frame_num: u32,
}

async fn atomic_write<P: AsRef<Path>>(path: P, data: &[u8]) -> Result<()> {
// Create a temporary file in the same directory as the target file
let directory = path.as_ref().parent().unwrap();

let temp_name = format!(".tmp.{}", Uuid::new_v4());
let temp_path = directory.join(temp_name);

// Write data to temporary file
let mut temp_file = tokio::fs::File::create(&temp_path).await.unwrap();

temp_file.write_all(data).await.unwrap();

// Ensure all data is flushed to disk
temp_file.sync_all().await.unwrap();

// Close the file explicitly
drop(temp_file);

// Atomically rename temporary file to target file
tokio::fs::rename(&temp_path, &path).await.unwrap();

Ok(())
}

0 comments on commit 4a8460f

Please sign in to comment.