Skip to content

Commit 644272d

Browse files
authored
fix FS watcher for linux (#156)
1 parent 021398d commit 644272d

File tree

4 files changed

+44
-33
lines changed

4 files changed

+44
-33
lines changed

Cargo.lock

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

rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ similar = { version = "2.4.0", features = ["unicode"] }
4141
notify = { version = "8.2.0", features = [
4242
"macos_fsevent",
4343
] }
44-
notify-debouncer-mini = { version = "0.7.0", features = [
44+
notify-debouncer-full = { version = "0.7.0", features = [
4545
"macos_fsevent",
4646
] }
4747
rand = "0.9.2"

rust/src/project/branch_db/commit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ impl BranchDb {
2727
) -> Option<HistoryRef> {
2828
tracing::info!("Attempting to commit changes...");
2929
// Only commit files that have actually changed
30+
// TODO: We may be able to use notify's compare file hash system instead? Or in addition to this?
3031
let files = self.filter_changed_files(ref_, files).await;
3132
let count = files.len();
3233
let username = self.username.lock().await.clone();

rust/src/project/fs_watcher.rs

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use std::{
88
use async_stream::stream;
99
use futures::Stream;
1010
use md5::Digest;
11-
use notify::{Config, RecommendedWatcher, RecursiveMode};
12-
use notify_debouncer_mini::{DebouncedEvent, new_debouncer_opt};
11+
use notify::RecursiveMode;
12+
use notify_debouncer_full::{DebounceEventResult, new_debouncer};
1313
use tokio::{
1414
sync::{
1515
Mutex,
@@ -154,12 +154,12 @@ impl FileSystemWatcher {
154154
Ok(None)
155155
}
156156

157-
async fn process_notify_event(&self, event: DebouncedEvent) -> Option<FileSystemEvent> {
158-
if self.branch_db.should_ignore(&event.path) {
157+
async fn process_notify_path(&self, path: &PathBuf) -> Option<FileSystemEvent> {
158+
if self.branch_db.should_ignore(path) {
159159
return None;
160160
}
161-
tracing::debug!("handling filesystem event: {:?}", event.path);
162-
let result = self.handle_file_event(event.path.clone()).await;
161+
tracing::debug!("handling filesystem event: {:?}", path);
162+
let result = self.handle_file_event(path.clone()).await;
163163
if let Ok(Some(ret)) = result {
164164
return Some(ret);
165165
}
@@ -172,29 +172,22 @@ impl FileSystemWatcher {
172172
branch_db: BranchDb,
173173
) -> impl Stream<Item = FileSystemEvent> {
174174
let (notify_tx, notify_rx) = mpsc::unbounded_channel();
175-
let notify_config = Config::default()
176-
.with_follow_symlinks(false);
177-
178-
let debouncer_config = notify_debouncer_mini::Config::default()
179-
.with_timeout(Duration::from_millis(100))
180-
.with_batch_mode(true)
181-
.with_notify_config(notify_config);
182-
183175
let notify_tx_clone = notify_tx.clone();
184-
let mut debouncer = new_debouncer_opt::<_, RecommendedWatcher>(
185-
debouncer_config,
186-
move |event: Result<Vec<notify_debouncer_mini::DebouncedEvent>, notify::Error>| {
187-
notify_tx_clone.send(event).unwrap();
176+
let mut debouncer = new_debouncer(
177+
Duration::from_millis(100),
178+
None,
179+
move |events: DebounceEventResult| {
180+
let Ok(events) = events else {
181+
return;
182+
};
183+
notify_tx_clone.send(events).unwrap();
188184
},
189185
)
190186
.unwrap();
191187

192188
// Begin the watch
193189
// I'm assuming that notify uses good RAII and stops watching when we kill the handle.... hopefully.
194-
debouncer
195-
.watcher()
196-
.watch(&path, RecursiveMode::Recursive)
197-
.unwrap();
190+
debouncer.watch(&path, RecursiveMode::Recursive).unwrap();
198191

199192
let this = FileSystemWatcher {
200193
watch_path: path,
@@ -205,7 +198,7 @@ impl FileSystemWatcher {
205198

206199
this.initialize_file_hashes().await;
207200
for path in this.found_ignored_paths.lock().await.iter() {
208-
let _ret = debouncer.watcher().unwatch(path);
201+
let _ret = debouncer.unwatch(path);
209202
}
210203
let stream = UnboundedReceiverStream::new(notify_rx);
211204
// Process both file system events and update eventss
@@ -214,12 +207,19 @@ impl FileSystemWatcher {
214207
let _keep_alive = debouncer;
215208
// Handle file system events
216209
for await notify_events in stream {
217-
let Ok(notify_events) = notify_events else {
218-
continue;
219-
};
220210
for notify_event in notify_events {
221-
if let Some(evt) = this.process_notify_event(notify_event).await {
222-
yield evt;
211+
match notify_event.kind {
212+
notify::EventKind::Any => continue,
213+
notify::EventKind::Access(_) => continue,
214+
notify::EventKind::Create(_) => (),
215+
notify::EventKind::Modify(_) => (),
216+
notify::EventKind::Remove(_) => (),
217+
notify::EventKind::Other => continue,
218+
};
219+
for path in &notify_event.paths {
220+
if let Some(evt) = this.process_notify_path(path).await {
221+
yield evt;
222+
}
223223
}
224224
}
225225
}

0 commit comments

Comments
 (0)