From 7aba8706b3723b84d930aa80107d1f15807134f4 Mon Sep 17 00:00:00 2001 From: Issac Kelly Date: Fri, 15 Sep 2023 13:45:12 -0700 Subject: [PATCH] Catch situation where current snapshot is being deleted --- src/fs_store.rs | 42 ++++++++++++++++++++++++++++++++---------- src/repo.rs | 4 ++-- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/fs_store.rs b/src/fs_store.rs index 83181bd..b5d691c 100644 --- a/src/fs_store.rs +++ b/src/fs_store.rs @@ -129,7 +129,7 @@ impl FsStore { .map_err(|e| Error(ErrorKind::ErrReadingLevel1Path(entry.path(), e)))? .is_file() { - tracing::warn!( + tracing::trace!( non_dir_path=%entry.path().display(), "unexpected non-directory at level1 of database" ); @@ -146,14 +146,14 @@ impl FsStore { .metadata() .map_err(|e| Error(ErrorKind::ErrReadingLevel2Path(entry.path(), e)))?; if !metadata.is_dir() { - tracing::warn!( + tracing::trace!( non_dir_path=%entry.path().display(), "unexpected non-directory at level2 of database" ); continue; } let Some(doc_paths) = DocIdPaths::parse(entry.path()) else { - tracing::warn!( + tracing::trace!( non_doc_path=%entry.path().display(), "unexpected non-document path at level2 of database" ); @@ -193,7 +193,13 @@ impl FsStore { // Write the snapshot let output_chunk_name = SavedChunkName::new_snapshot(doc.get_heads()); let chunk = doc.save(); - write_chunk(&self.root, &paths, &chunk, output_chunk_name, &self.tmpdir)?; + write_chunk( + &self.root, + &paths, + &chunk, + output_chunk_name.clone(), + &self.tmpdir, + )?; // Remove all the old data for incremental in chunks.incrementals.keys() { @@ -201,8 +207,19 @@ impl FsStore { std::fs::remove_file(&path) .map_err(|e| Error(ErrorKind::DeleteChunk(path, e)))?; } + let just_wrote = paths.chunk_path(&self.root, &output_chunk_name); for snapshot in chunks.snapshots.keys() { let path = paths.chunk_path(&self.root, snapshot); + + if path == just_wrote { + tracing::error!( + ?path, + "Somehow trying to delete the same path we just wrote to. Not today \ + Satan" + ); + continue; + } + std::fs::remove_file(&path) .map_err(|e| Error(ErrorKind::DeleteChunk(path, e)))?; } @@ -261,6 +278,7 @@ fn write_chunk( // Move the temporary file into a snapshot in the document data directory // with a name based on the hash of the heads of the document let output_path = paths.chunk_path(root, &name); + tracing::trace!(?temp_save_path, ?output_path, "renaming chunk file"); std::fs::rename(&temp_save_path, &output_path) .map_err(|e| Error(ErrorKind::RenameTempFile(temp_save_path, output_path, e)))?; @@ -327,13 +345,13 @@ impl DocIdPaths { } } -#[derive(Debug, Hash, PartialEq, Eq)] +#[derive(Debug, Hash, PartialEq, Eq, Clone)] enum ChunkType { Snapshot, Incremental, } -#[derive(Debug, Hash, PartialEq, Eq)] +#[derive(Debug, Hash, PartialEq, Eq, Clone)] struct SavedChunkName { hash: Vec, chunk_type: ChunkType, @@ -432,12 +450,12 @@ impl Chunks { .map_err(|e| Error(ErrorKind::ErrReadingChunkFileMetadata(path.clone(), e)))? .is_file() { - tracing::warn!(bad_file=%path.display(), "unexpected non-file in level2 path"); + tracing::trace!(bad_file=%path.display(), "unexpected non-file in level2 path"); continue; } let Some(chunk_name) = entry.file_name().to_str().and_then(SavedChunkName::parse) else { - tracing::warn!(bad_file=%path.display(), "unexpected non-chunk file in level2 path"); + tracing::trace!(bad_file=%path.display(), "unexpected non-chunk file in level2 path"); continue; }; tracing::debug!(chunk_path=%path.display(), "reading chunk file"); @@ -447,7 +465,7 @@ impl Chunks { match e.kind() { std::io::ErrorKind::NotFound => { // Could be a concurrent process compacting, not an error - tracing::warn!( + tracing::trace!( missing_chunk_path=%path.display(), "chunk file disappeared while reading chunks", ); @@ -480,7 +498,11 @@ impl Chunks { for chunk in self.incrementals.values() { bytes.extend(chunk); } - automerge::Automerge::load(&bytes) + + automerge::Automerge::load_with_options( + &bytes, + automerge::LoadOptions::new().on_partial_load(automerge::OnPartialLoad::Ignore), + ) } } diff --git a/src/repo.rs b/src/repo.rs index 9e57799..e4d75b1 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -713,8 +713,8 @@ impl DocumentInfo { changes.len() }; let has_patches = count > 0; - self.saves_since_last_compact = self - .saves_since_last_compact + self.changes_since_last_compact = self + .changes_since_last_compact .checked_add(count) .unwrap_or(0); has_patches