Skip to content

Commit 6a982db

Browse files
authored
only persist documents to S3 when dirty (#416)
Fix an issue where y-sweet was persisting documents to S3 every ~10 seconds even when no changes had occurred. From what I understand, the persistence worker wakes up both on the dirty signal and also on a `checkpoint_freq` interval and was always calling persist, regardless of the dirtiness, which would write it to S3 regardless of whether any changes had been made. The fix adds a check to only persist when the document is actually dirty. I'm still a little bit unclear behind the reasoning for the logic of signaling the worker both on a dirty callback and on a timer. So I wonder if we instead just start the worker once, wake every 10 seconds, check if dirty, persist if needed.
1 parent e492348 commit 6a982db

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

crates/y-sweet-core/src/sync_kv.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,17 @@ impl SyncKv {
5656
}
5757
}
5858

59+
pub fn is_dirty(&self) -> bool {
60+
self.dirty.load(Ordering::Relaxed)
61+
}
62+
5963
pub async fn persist(&self) -> Result<(), Box<dyn std::error::Error>> {
64+
// Only persist if actually dirty
65+
if !self.is_dirty() {
66+
tracing::info!("Not persisting, no changes detected");
67+
return Ok(());
68+
}
69+
6070
if let Some(store) = &self.store {
6171
let snapshot = {
6272
let data = self.data.lock().unwrap();
@@ -299,4 +309,29 @@ mod test {
299309
assert_eq!(sync_kv.get(b"foo"), Some(b"bar".to_vec()));
300310
}
301311
}
312+
313+
#[tokio::test]
314+
async fn only_persists_when_dirty() {
315+
let store = MemoryStore::default();
316+
let sync_kv = SyncKv::new(Some(Arc::new(Box::new(store.clone()))), "foo", || ())
317+
.await
318+
.unwrap();
319+
320+
assert!(!sync_kv.is_dirty());
321+
322+
sync_kv.set(b"foo", b"bar");
323+
assert!(sync_kv.is_dirty());
324+
325+
sync_kv.persist().await.unwrap();
326+
assert!(!sync_kv.is_dirty());
327+
assert_eq!(store.data.len(), 1);
328+
329+
store.data.clear();
330+
331+
assert!(!sync_kv.is_dirty());
332+
sync_kv.persist().await.unwrap();
333+
334+
// Should not persist when not dirty
335+
assert!(store.data.is_empty());
336+
}
302337
}

0 commit comments

Comments
 (0)