diff options
author | edef <edef@unfathomable.blue> | 2022-04-28 21:40:08 +0000 |
---|---|---|
committer | edef <edef@unfathomable.blue> | 2022-04-28 21:40:08 +0000 |
commit | b5a97ad86e81e3bd8ff325ea991459c5f262b245 (patch) | |
tree | 5802a3096c288c36d5539a6026f82df5f5fd4f80 | |
parent | c08692df2c43c4c4e71691b83f43e4012aa6315e (diff) | |
download | unf-legacy-b5a97ad86e81e3bd8ff325ea991459c5f262b245.tar.zst |
ripple/fossil: ensure durability of add_path
sled doesn't actually promise not to eat your data until you invoke flush. This is observable under normal circumstances as add_path occasionally just not committing anything to the store. While we're at it, ensure we're syncing the chunks file data to disk, so the database *might* actually be consistent. We're not going for full crash-correctness yet, mostly for performance and complexity reasons. Change-Id: I6cc69a013dc18cd50df26e73801b185de596565c
-rw-r--r-- | ripple/fossil/src/lib.rs | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/ripple/fossil/src/lib.rs b/ripple/fossil/src/lib.rs index 4cea16a..c79105c 100644 --- a/ripple/fossil/src/lib.rs +++ b/ripple/fossil/src/lib.rs @@ -66,6 +66,20 @@ impl Store { pub fn add_path(&self, path: impl AsRef<Path>) -> Node { let path = path.as_ref(); + let node = self.add_path_inner(path); + + // NOTE: sled *can* flush without us explicitly asking for it, so it's + // possible for the store to end up containing pointers to chunks that + // aren't fsynced yet. The easiest fix is to always `chunks_file.sync_data()` + // before we write anything to the database, but that's kind of a performance hazard. + // TODO(edef): keep pending and known-durable blobs/chunks separate in the database + self.chunks_file.borrow_mut().sync_data().unwrap(); + self.meta.flush().unwrap(); + + node + } + + fn add_path_inner(&self, path: &Path) -> Node { let meta = fs::symlink_metadata(path).unwrap(); match meta.file_type() { @@ -151,7 +165,6 @@ impl Store { buf }; - // TODO(edef): figure out fsync for durability (&self.blobs, &self.chunks, &self.meta) .transaction(|(blobs, chunks, meta)| { chunks.apply_batch(&batch)?; |