Optimize the notify event handler

This commit is contained in:
mo8it 2024-04-25 14:44:12 +02:00
parent 88f27a5377
commit 14fe248b4b
3 changed files with 22 additions and 13 deletions

View file

@ -144,23 +144,23 @@ fn main() -> Result<()> {
match args.command { match args.command {
None => { None => {
let notify_exercise_paths: Option<&'static [&'static str]> = if args.manual_run { let notify_exercise_names = if args.manual_run {
None None
} else { } else {
// For the the notify event handler thread. // For the the notify event handler thread.
// Leaking is not a problem because the slice lives until the end of the program. // Leaking is not a problem because the slice lives until the end of the program.
Some( Some(
app_state &*app_state
.exercises() .exercises()
.iter() .iter()
.map(|exercise| exercise.path) .map(|exercise| exercise.name.as_bytes())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.leak(), .leak(),
) )
}; };
loop { loop {
match watch::watch(&mut app_state, notify_exercise_paths)? { match watch::watch(&mut app_state, notify_exercise_names)? {
WatchExit::Shutdown => break, WatchExit::Shutdown => break,
// It is much easier to exit the watch mode, launch the list mode and then restart // It is much easier to exit the watch mode, launch the list mode and then restart
// the watch mode instead of trying to pause the watch threads and correct the // the watch mode instead of trying to pause the watch threads and correct the

View file

@ -42,19 +42,19 @@ pub enum WatchExit {
pub fn watch( pub fn watch(
app_state: &mut AppState, app_state: &mut AppState,
notify_exercise_paths: Option<&'static [&'static str]>, notify_exercise_names: Option<&'static [&'static [u8]]>,
) -> Result<WatchExit> { ) -> Result<WatchExit> {
let (tx, rx) = channel(); let (tx, rx) = channel();
let mut manual_run = false; let mut manual_run = false;
// Prevent dropping the guard until the end of the function. // Prevent dropping the guard until the end of the function.
// Otherwise, the file watcher exits. // Otherwise, the file watcher exits.
let _debouncer_guard = if let Some(exercise_paths) = notify_exercise_paths { let _debouncer_guard = if let Some(exercise_names) = notify_exercise_names {
let mut debouncer = new_debouncer( let mut debouncer = new_debouncer(
Duration::from_millis(500), Duration::from_millis(500),
DebounceEventHandler { DebounceEventHandler {
tx: tx.clone(), tx: tx.clone(),
exercise_paths, exercise_names,
}, },
) )
.inspect_err(|_| eprintln!("{NOTIFY_ERR}"))?; .inspect_err(|_| eprintln!("{NOTIFY_ERR}"))?;

View file

@ -5,7 +5,7 @@ use super::WatchEvent;
pub struct DebounceEventHandler { pub struct DebounceEventHandler {
pub tx: Sender<WatchEvent>, pub tx: Sender<WatchEvent>,
pub exercise_paths: &'static [&'static str], pub exercise_names: &'static [&'static [u8]],
} }
impl notify_debouncer_mini::DebounceEventHandler for DebounceEventHandler { impl notify_debouncer_mini::DebounceEventHandler for DebounceEventHandler {
@ -15,15 +15,24 @@ impl notify_debouncer_mini::DebounceEventHandler for DebounceEventHandler {
let Some(exercise_ind) = event let Some(exercise_ind) = event
.iter() .iter()
.filter_map(|event| { .filter_map(|event| {
if event.kind != DebouncedEventKind::Any if event.kind != DebouncedEventKind::Any {
|| !event.path.extension().is_some_and(|ext| ext == "rs")
{
return None; return None;
} }
self.exercise_paths let file_name = event.path.file_name()?.to_str()?.as_bytes();
if file_name.len() < 4 {
return None;
}
let (file_name_without_ext, ext) = file_name.split_at(file_name.len() - 3);
if ext != b".rs" {
return None;
}
self.exercise_names
.iter() .iter()
.position(|path| event.path.ends_with(path)) .position(|exercise_name| *exercise_name == file_name_without_ext)
}) })
.min() .min()
else { else {