Parcourir la source

Add code to iterate through file system events.

Mathias Gottschlag il y a 5 ans
Parent
révision
27e67d3629
1 fichiers modifiés avec 65 ajouts et 32 suppressions
  1. 65
    32
      src/file_system_watcher.rs

+ 65
- 32
src/file_system_watcher.rs Voir le fichier

@@ -1,11 +1,11 @@
1
-use std::collections::{VecDeque, HashMap};
2 1
 use std::sync::Arc;
3
-use std::path::Path;
4 2
 use std::time::Duration;
5 3
 
4
+use fswatcher::{FileEventDelay, FileSystemEvent};
5
+use futures::future::{self, Either};
6
+use tokio::stream::StreamExt;
6 7
 use tokio::sync::{mpsc, oneshot, Mutex};
7 8
 use tokio::task;
8
-use fswatcher::FileEventDelay;
9 9
 
10 10
 use super::{Error, FileTree};
11 11
 
@@ -73,45 +73,78 @@ impl FileSystemWatcher {
73 73
 
74 74
     async fn task_unpaused(
75 75
         file_tree: &mut Arc<Mutex<FileTree>>,
76
-        _state_receive: &mut mpsc::Receiver<(StateChange, oneshot::Sender<()>)>,
76
+        state_receive: &mut mpsc::Receiver<(StateChange, oneshot::Sender<()>)>,
77 77
     ) -> StateChange {
78 78
         let root_path = file_tree.lock().await.root_path().to_owned();
79 79
         // TODO: Proper error handling.
80
-        let file_events = FileEventDelay::new(fswatcher::FileSystemWatcher::new(&root_path).unwrap(), Duration::from_secs(3));
80
+        let mut file_events = FileEventDelay::new(
81
+            fswatcher::FileSystemWatcher::new(&root_path).unwrap(),
82
+            Duration::from_secs(3),
83
+        );
81 84
 
82 85
         loop {
83
-            /*if new_directories.is_empty() {
84
-                // If all the inotify watches are up-to-date, simply wait for any events.
85
-                let event = file_events.next(&paths_by_watch).await;
86
-                // TODO
87
-            } else {
88
-                // Install an inotify watch for the directory and check the directory contents
89
-                // against the database.
90
-                let new_directory = new_directories.pop_front().unwrap();
91
-                // TODO: Do not follow links!
92
-                // TODO: Is ONLYDIR correct?
93
-                // TODO: We want to delay events for 2-3 seconds, so that we limit the rate of
94
-                // modification events and so that we are maybe able to detect moved
95
-                // files/directories across different directories!
96
-                if Path::new(&new_directory).is_dir() {
97
-                    let watch = inotify.add_watch(new_directory, WatchMask::ATTRIB | WatchMask::CLOSE_WRITE | WatchMask::CREATE | WatchMask::DELETE | WatchMask::DELETE_SELF | WatchMask::MODIFY | WatchMask::MOVE | WatchMask::EXCL_UNLINK | WatchMask::ONLYDIR);
98
-                    // TODO
86
+            match future::select(Box::pin(file_events.next()), Box::pin(state_receive.recv())).await
87
+            {
88
+                Either::Left((event, _state_future)) => {
89
+                    // TODO: Error handling, handle None event.
90
+                    Self::handle_file_event(file_tree, event.unwrap()).await;
99 91
                 }
92
+                Either::Right((next_state, _file_event_future)) => {
93
+                    match next_state.unwrap() {
94
+                        (StateChange::Unpause, send) => send.send(()).unwrap(),
95
+                        (StateChange::Pause, send) => {
96
+                            send.send(()).unwrap();
97
+                            return StateChange::Pause;
98
+                        }
99
+                        (StateChange::Terminate, _) => return StateChange::Pause,
100
+                    };
101
+                }
102
+            };
103
+        }
104
+    }
100 105
 
101
-                // Proceed recursively at the next loop iteration.
106
+    async fn handle_file_event(_file_tree: &mut Arc<Mutex<FileTree>>, event: FileSystemEvent) {
107
+        match event {
108
+            FileSystemEvent::Stopped(_reason) => {
102 109
                 // TODO
103
-
104
-                // Poll for events (without blocking, so that we immediately process the next
105
-                // directory if nothing happened).
110
+            }
111
+            FileSystemEvent::DirectoryWatched(_path) => {
106 112
                 // TODO
107
-
108
-                // Yield to other parts of the program to minimize the impact of scanning large
109
-                // directory trees.
110
-                // TODO: Check whether this is really necessary and how large the impact on
111
-                // performance is.
112
-                task::yield_now().await;
113
-            }*/
113
+            }
114
+            FileSystemEvent::DirectoryCreated(_path) => {
115
+                // TODO
116
+            }
117
+            FileSystemEvent::DirectoryModified(_path) => {
118
+                // TODO
119
+            }
120
+            FileSystemEvent::DirectoryRemoved(_path) => {
121
+                // TODO
122
+            }
123
+            FileSystemEvent::DirectoryMoved(_from, _to) => {
124
+                // TODO
125
+            }
126
+            FileSystemEvent::FileCreated(_path) => {
127
+                // TODO
128
+            }
129
+            FileSystemEvent::FileModified(_path) => {
130
+                // TODO
131
+            }
132
+            FileSystemEvent::FileRemoved(_path) => {
133
+                // TODO
134
+            }
135
+            FileSystemEvent::FileMoved(_from, _to) => {
136
+                // TODO
137
+            }
138
+            FileSystemEvent::Error(_e) => {
139
+                // TODO
140
+            }
114 141
         }
142
+
143
+        // Yield to other parts of the program to minimize the impact of scanning large
144
+        // directory trees.
145
+        // TODO: Check whether this is really necessary and how large the impact on
146
+        // performance is.
147
+        task::yield_now().await;
115 148
     }
116 149
 }
117 150
 

Loading…
Annuler
Enregistrer