diff --git a/crates/engine/src/autosave.rs b/crates/engine/src/autosave.rs index c6b41cce4..9ff7eab0b 100644 --- a/crates/engine/src/autosave.rs +++ b/crates/engine/src/autosave.rs @@ -416,6 +416,13 @@ mod native { writes } + /// Whether a background write hasn't finished yet. Its file can exist before it finishes + /// (the folder is synced after the rename), and until [`Autosaver::reap`] takes it in, the + /// drawing is left out of planning. + pub fn writing(&self) -> bool { + self.running.iter().any(|(_, h)| !h.is_finished()) + } + /// Take in the writes that have finished ([`Autosaver::tick`] does this first). A drawing /// whose write failed is no longer counted as autosaved: the next plan restarts its clock, /// so it is tried again SAVETIME later even if it doesn't change. diff --git a/crates/engine/tests/autosave.rs b/crates/engine/tests/autosave.rs index da03c0d7d..f44be5231 100644 --- a/crates/engine/tests/autosave.rs +++ b/crates/engine/tests/autosave.rs @@ -185,6 +185,14 @@ fn autosave_files_are_written_in_the_background_and_removed_on_exit() { std::thread::sleep(Duration::from_millis(10)); } assert!(std::fs::read(&path).unwrap().ends_with(b"EOF\n")); + // The file exists before the write finishes (the folder sync comes after the rename); until + // it has, the drawing is busy and the change drawn below would not be planned. + for _ in 0..500 { + if !a.writing() { + break; + } + std::thread::sleep(Duration::from_millis(10)); + } // While the app runs, its lock keeps its files out of recovery. SAVETIME and SAVEFILEPATH // are system variables (process-wide, so set in this test only). assert_eq!(cadcraft_engine::sysvars::get(&s, "SAVETIME"), Some(json!(10)));