Skip to content

Commit e0c1c37

Browse files
committed
fix: finally added debounce impl and removed the unnecessary multiple responses for single changes
1 parent a542937 commit e0c1c37

File tree

3 files changed

+63
-28
lines changed

3 files changed

+63
-28
lines changed

Cargo.lock

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ ammonia = "4.1.1"
1717
askama = { version = "0.14.0", features = ["full"] }
1818
clap = { version = "4.5.46", features = ["derive"] }
1919
notify = "8.2.0"
20+
notify-debouncer-full = "0.7.0"
2021
pulldown-cmark = "0.13.0"
2122
rust-embed = { version = "8.11.0", features = ["interpolate-folder-path"] }
2223
tokio = { version = "1.49.0", features = ["full"] }

src/main.rs

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
#![allow(unused)]
12
use actix_web::web;
3+
use notify::event::RemoveKind;
4+
use notify_debouncer_full::DebouncedEvent;
5+
use notify_debouncer_full::{DebounceEventResult, new_debouncer, notify::*};
26
use pulldown_cmark::Options;
37
use std::fs;
48
use std::path::Path;
9+
use tokio::time::Duration;
510
mod args;
611
use actix_web::App;
712
use actix_web::HttpServer;
@@ -13,7 +18,7 @@ use args::MdwatchArgs;
1318
use askama::Template;
1419
use clap::Parser;
1520

16-
use notify::{Event, RecursiveMode, Result, Watcher};
21+
use notify::{Event, RecursiveMode, Result, Watcher, event::ModifyKind};
1722
use rust_embed::Embed;
1823
use tokio::sync::mpsc;
1924

@@ -63,41 +68,47 @@ async fn ws_handler(
6368
) -> actix_web::Result<impl Responder> {
6469
let (response, mut session, mut _msg_stream) = actix_ws::handle(&req, body)?;
6570
let file_path = file.as_str().to_string();
66-
let (watch_tx, mut notify_rx) = mpsc::unbounded_channel::<Result<Event>>();
67-
68-
let mut watcher = notify::recommended_watcher(move |res| {
69-
let _ = watch_tx.send(res);
70-
})
71+
let (watch_tx, mut notify_rx) = mpsc::unbounded_channel::<DebouncedEvent>();
72+
73+
let mut debouncer = new_debouncer(
74+
Duration::from_secs(2),
75+
None,
76+
move |result: DebounceEventResult| match result {
77+
Ok(events) => events.into_iter().for_each(|event| {
78+
let _ = watch_tx.send(event);
79+
}),
80+
Err(errors) => errors
81+
.iter()
82+
.for_each(|error| eprintln!("watch error: {error:?}")),
83+
},
84+
)
7185
.map_err(actix_web::error::ErrorInternalServerError)?;
7286

73-
watcher
74-
.watch(Path::new(&file_path), RecursiveMode::NonRecursive)
87+
debouncer
88+
.watch(&file_path, RecursiveMode::NonRecursive)
7589
.map_err(actix_web::error::ErrorInternalServerError)?;
7690

7791
actix_web::rt::spawn(async move {
7892
// Keep the watcher alive in this async task to keep the msg_stream alive
79-
let _watcher = watcher;
80-
while let Some(res) = notify_rx.recv().await {
81-
match res {
82-
Ok(event) => {
83-
if event.kind.is_remove() {
84-
eprintln!("File removed: {}", file_path);
85-
break;
86-
}
87-
if event.kind.is_modify() {
88-
let latest_markdown = match get_markdown(&file_path) {
89-
Ok(md) => md,
90-
Err(e) => {
91-
eprintln!("Error reading markdown file: {e}");
92-
continue;
93-
}
94-
};
95-
if session.text(latest_markdown).await.is_err() {
96-
break;
97-
}
93+
let _watcher = debouncer;
94+
95+
while let Some(event) = notify_rx.recv().await {
96+
if matches!(event.kind, EventKind::Remove(RemoveKind::File)) {
97+
eprintln!("File removed: {}", file_path);
98+
break;
99+
}
100+
if matches!(event.kind, EventKind::Modify(ModifyKind::Data(_))) {
101+
println!("File modified");
102+
let latest_markdown = match get_markdown(&file_path) {
103+
Ok(md) => md,
104+
Err(e) => {
105+
eprintln!("Error reading markdown file: {e}");
106+
continue;
98107
}
108+
};
109+
if session.text(latest_markdown).await.is_err() {
110+
break;
99111
}
100-
Err(e) => eprintln!("watch error: {e:?}"),
101112
}
102113
}
103114

0 commit comments

Comments
 (0)