diff --git a/crates/snowbound/src/prefetch.rs b/crates/snowbound/src/prefetch.rs index 17c6764037d229aa0a756664785be0df8cbbff1e..5e450671a70c2e5d345f59d593b4566891cd95cf 100644 --- a/crates/snowbound/src/prefetch.rs +++ b/crates/snowbound/src/prefetch.rs @@ -208,6 +208,9 @@ fn prepare(job: Job, layouts: &Mutex, scenes: &Scenes) -> Result<(), last, notify, } => { + let Some(_structure) = library.structure.try_lock() else { + return Ok(()); + }; let replica = library.prefetch(&path, notify)?; let pages = replica.pages()?; let space = last @@ -360,6 +363,47 @@ impl State { mod tests { use super::*; + #[test] + fn section_prefetch_skips_while_notebook_structure_changes() { + use notebook::session::Notebook; + + let root = std::env::temp_dir().join(format!("snowbound-prefetch-{}", std::process::id())); + let _ = notebook::fs::remove_dir_all(&root); + notebook::fs::create_dir_all(&root).unwrap(); + let cache = root.join("cache"); + let page = onestore::PageCreation::new(None, Some("original"), "Fixture").unwrap(); + let notebook = + Notebook::create(root.join("Personal"), &cache, Notebook::NEW_COLOR, &page).unwrap(); + let path = "New Section 1.one"; + let replica = notebook.replica_path(path).unwrap(); + drop(notebook); + let library = Arc::new(Library::notebook( + root.join("Personal").to_str().unwrap(), + &cache, + )); + if let Some(background) = &library.background { + background.stop(); + } + assert!(notebook::fs::metadata(&replica).is_err()); + { + let _changing = library.structure.try_lock().unwrap(); + prepare( + Job::Section { + library: Arc::clone(&library), + path: path.into(), + last: None, + notify: Box::new(|| {}), + }, + &Mutex::new(TextEngine::default()), + &Scenes::new(Mutex::new(Recent::new(SCENES))), + ) + .unwrap(); + assert!(notebook::fs::metadata(&replica).is_err()); + } + drop(library); + notebook::fs::remove_dir_all(root).unwrap(); + } + #[test] fn the_least_recent_go_first_past_the_count() { let mut recent = Recent::new(2);