diff --git a/apps/figcraft-server/src/store/backend.rs b/apps/figcraft-server/src/store/backend.rs index ee4091a8b..5d4a3bfe9 100644 --- a/apps/figcraft-server/src/store/backend.rs +++ b/apps/figcraft-server/src/store/backend.rs @@ -68,7 +68,9 @@ impl Backend for Store { Err(err) => log::error!("file {file}: a change couldn't be logged: {err}"), } } - log.entries += journal.len(); + // A refusal changes nothing in the document: it counts toward the log's size (bytes), but + // not toward the entries that make a snapshot rewrite worthwhile. + log.entries += journal.iter().filter(|j| !matches!(j, figcraft_collab::Journal::Refused { .. })).count(); log.dirty = true; e.meta.updated = now(); if log.entries >= after || log.bytes + log.pending.len() as u64 >= max_bytes { diff --git a/apps/figcraft-server/src/store_tests.rs b/apps/figcraft-server/src/store_tests.rs index f94e76f02..f2074d879 100644 --- a/apps/figcraft-server/src/store_tests.rs +++ b/apps/figcraft-server/src/store_tests.rs @@ -155,6 +155,24 @@ fn read_only_sessions_keep_client_ids_without_rewriting_the_snapshot() { } } +#[test] +fn a_viewers_refused_batches_do_not_rewrite_the_snapshot() { + let dir = TempDir::new("refusals"); + let c = StoreConfig { compact_after: 3, ..cfg(dir.path()) }; + let mut store = Store::open(dir.path(), c).unwrap(); + let (id, _, _) = publish(&mut store, "Busy"); + let mut server = store.open(&id).unwrap(); + let mut v = join(&mut server, Access::View); + store.changed(&id, &mut server); + let generation = || disk::check_snapshot(&fs::read(dir.path().join(FILES).join(&id).join(SNAPSHOT)).unwrap()).unwrap(); + assert_eq!(generation(), 1); + for i in 0..10 { + rename(&mut server, &mut v, &format!("P{i}")); + store.changed(&id, &mut server); + } + assert_eq!(generation(), 1, "refusals are logged, not compacted"); +} + #[test] fn a_long_log_is_compacted_while_open() { let dir = TempDir::new("compact");