Fix high CPU usage due to inotify watch triggering itself (#5905)

Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
aodenis 2025-02-25 13:41:54 +01:00 committed by GitHub
parent 225e845021
commit acd3a5b7a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -204,6 +204,10 @@ impl Watcher {
let event = event let event = event
.map_err(|err| eco_format!("failed to watch dependencies ({err})"))?; .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 // Workaround for notify-rs' implicit unwatch on remove/rename
// (triggered by some editors when saving files) with the // (triggered by some editors when saving files) with the
// inotify backend. By keeping track of the potentially // 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 // 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. /// Whether a kind of watch event is relevant for compilation.
fn is_event_relevant(&self, event: &notify::Event) -> bool { fn is_relevant_event_kind(kind: &notify::EventKind) -> bool {
// Never recompile because the output file changed. match kind {
if event notify::EventKind::Any => true,
.paths notify::EventKind::Access(_) => false,
.iter() notify::EventKind::Create(_) => true,
.all(|path| is_same_file(path, &self.output).unwrap_or(false)) notify::EventKind::Modify(kind) => match kind {
{ notify::event::ModifyKind::Any => true,
return false; notify::event::ModifyKind::Data(_) => true,
} notify::event::ModifyKind::Metadata(_) => false,
notify::event::ModifyKind::Name(_) => true,
match &event.kind { notify::event::ModifyKind::Other => false,
notify::EventKind::Any => true, },
notify::EventKind::Access(_) => false, notify::EventKind::Remove(_) => true,
notify::EventKind::Create(_) => true, notify::EventKind::Other => false,
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,
}
} }
} }