diff options
| author | aodenis <45949528+aodenis@users.noreply.github.com> | 2025-02-25 13:41:54 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-25 12:41:54 +0000 |
| commit | acd3a5b7a5999d22fbf2da488744d564b2f3638e (patch) | |
| tree | 1578194f5a7097a59be2621ffc01cea683f4d148 /crates | |
| parent | 225e845021b9cfb37e6dc719c8bc85ccdc1ff69f (diff) | |
Fix high CPU usage due to inotify watch triggering itself (#5905)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/typst-cli/src/watch.rs | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/crates/typst-cli/src/watch.rs b/crates/typst-cli/src/watch.rs index 91132fc3..cc727f0f 100644 --- a/crates/typst-cli/src/watch.rs +++ b/crates/typst-cli/src/watch.rs @@ -204,6 +204,10 @@ impl Watcher { let event = event .map_err(|err| eco_format!("failed to watch dependencies ({err})"))?; + if !is_relevant_event_kind(&event.kind) { + continue; + } + // Workaround for notify-rs' implicit unwatch on remove/rename // (triggered by some editors when saving files) with the // inotify backend. By keeping track of the potentially @@ -224,7 +228,17 @@ impl Watcher { } } - relevant |= self.is_event_relevant(&event); + // Don't recompile because the output file changed. + // FIXME: This doesn't work properly for multifile image export. + if event + .paths + .iter() + .all(|path| is_same_file(path, &self.output).unwrap_or(false)) + { + continue; + } + + relevant = true; } // If we found a relevant event or if any of the missing files now @@ -234,32 +248,23 @@ impl Watcher { } } } +} - /// Whether a watch event is relevant for compilation. - fn is_event_relevant(&self, event: ¬ify::Event) -> bool { - // Never recompile because the output file changed. - if event - .paths - .iter() - .all(|path| is_same_file(path, &self.output).unwrap_or(false)) - { - return false; - } - - match &event.kind { - notify::EventKind::Any => true, - notify::EventKind::Access(_) => false, - notify::EventKind::Create(_) => true, - notify::EventKind::Modify(kind) => match kind { - notify::event::ModifyKind::Any => true, - notify::event::ModifyKind::Data(_) => true, - notify::event::ModifyKind::Metadata(_) => false, - notify::event::ModifyKind::Name(_) => true, - notify::event::ModifyKind::Other => false, - }, - notify::EventKind::Remove(_) => true, - notify::EventKind::Other => false, - } +/// Whether a kind of watch event is relevant for compilation. +fn is_relevant_event_kind(kind: ¬ify::EventKind) -> bool { + match kind { + notify::EventKind::Any => true, + notify::EventKind::Access(_) => false, + notify::EventKind::Create(_) => true, + notify::EventKind::Modify(kind) => match kind { + notify::event::ModifyKind::Any => true, + notify::event::ModifyKind::Data(_) => true, + notify::event::ModifyKind::Metadata(_) => false, + notify::event::ModifyKind::Name(_) => true, + notify::event::ModifyKind::Other => false, + }, + notify::EventKind::Remove(_) => true, + notify::EventKind::Other => false, } } |
