From fc268a4dbda7b4d8aa53fb0aba3bb668ac084c9a Mon Sep 17 00:00:00 2001 From: lbellows <19894143+lbellows@users.noreply.github.com> Date: Tue, 15 Sep 2026 08:04:37 -0400 Subject: [PATCH] fix: stop rewriting unchanged instance_files rows on every content sync The content sync stamped every scanned file with modified_at = now and upserted it, so an idle rescan rewrote every row in the instance even when nothing on disk had changed. Keep the stored stamp when the file is unchanged, and skip the upsert when the row already matches. --- .../instances/commands/sync_content_files.rs | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/app-lib/src/state/instances/commands/sync_content_files.rs b/packages/app-lib/src/state/instances/commands/sync_content_files.rs index 742135828e..bc92d5042c 100644 --- a/packages/app-lib/src/state/instances/commands/sync_content_files.rs +++ b/packages/app-lib/src/state/instances/commands/sync_content_files.rs @@ -153,6 +153,10 @@ pub(crate) async fn sync_instance_content_files( .iter() .map(|file| (file.relative_path.as_str(), file)) .collect::>(); + let existing_by_id = existing + .iter() + .map(|file| (file.id.as_str(), file)) + .collect::>(); let managed_by_path = existing .iter() .filter(|file| bindings.contains_key(&file.id)) @@ -265,6 +269,9 @@ pub(crate) async fn sync_instance_content_files( if let Some(previous) = previous { file.relative_path.clone_from(&previous.relative_path); file.file_name.clone_from(&previous.file_name); + if is_content_unchanged(&file, previous) { + file.modified_at = previous.modified_at; + } } else if !duplicate_paths.contains(canonical_path) { file.relative_path = canonical_path.to_string(); file.file_name = @@ -302,7 +309,15 @@ pub(crate) async fn sync_instance_content_files( } let mut stored = Vec::new(); for file in files { - if saved_files.contains(&file.id) { + if saved_files.contains(&file.id) + || existing_by_id + .get(file.id.as_str()) + .is_some_and(|previous| { + is_content_unchanged(&file, previous) + && file.modified_at.timestamp() + == previous.modified_at.timestamp() + }) + { stored.push(file); } else { stored.push( @@ -319,6 +334,21 @@ pub(crate) async fn sync_instance_content_files( Ok(stored) } +/// Whether a rescanned file matches what is already stored, ignoring +/// `modified_at` — which records when the file last actually changed, not when +/// it was last looked at. +fn is_content_unchanged( + candidate: &InstanceFile, + previous: &InstanceFile, +) -> bool { + candidate.relative_path == previous.relative_path + && candidate.file_name == previous.file_name + && candidate.enabled == previous.enabled + && candidate.sha1 == previous.sha1 + && candidate.size == previous.size + && candidate.missing == previous.missing +} + pub(super) async fn normalize_legacy_content_files( instance: &Instance, existing: &[InstanceFile],