From 16c3c1f49897d8bcbc1c4d37211c3ad91b407437 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Sat, 17 Nov 2018 13:51:22 -0800 Subject: [PATCH] Vfs -> Imfs, clean up and document a bit --- server/Cargo.lock | 10 +++----- server/Cargo.toml | 1 + server/src/fs_watcher.rs | 30 +++++++++++------------ server/src/{vfs.rs => imfs.rs} | 45 ++++++++++++++++++---------------- server/src/lib.rs | 2 +- server/src/rbx_session.rs | 24 +++++++++--------- server/src/session.rs | 18 +++++++------- server/tests/read_projects.rs | 2 -- test-projects/foo.json | 1 + 9 files changed, 67 insertions(+), 66 deletions(-) rename server/src/{vfs.rs => imfs.rs} (78%) diff --git a/server/Cargo.lock b/server/Cargo.lock index 3242e81a..9c2c0a85 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -349,11 +349,8 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "libc" @@ -698,6 +695,7 @@ version = "0.5.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -875,7 +873,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1117,7 +1115,7 @@ dependencies = [ "checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2" diff --git a/server/Cargo.toml b/server/Cargo.toml index 21cf0ba5..95369e2c 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -35,3 +35,4 @@ uuid = { version = "0.7", features = ["v4", "serde"] } [dev-dependencies] tempfile = "3.0" walkdir = "2.1" +lazy_static = "1.2" diff --git a/server/src/fs_watcher.rs b/server/src/fs_watcher.rs index 13a79027..a48319ef 100644 --- a/server/src/fs_watcher.rs +++ b/server/src/fs_watcher.rs @@ -13,18 +13,18 @@ use notify::{ }; use crate::{ - vfs::Vfs, + imfs::Imfs, rbx_session::RbxSession, }; const WATCH_TIMEOUT: Duration = Duration::from_millis(100); -fn handle_event(vfs: &Mutex, rbx_session: &Mutex, event: DebouncedEvent) { +fn handle_event(imfs: &Mutex, rbx_session: &Mutex, event: DebouncedEvent) { match event { DebouncedEvent::Create(path) => { { - let mut vfs = vfs.lock().unwrap(); - vfs.path_created(&path).unwrap(); + let mut imfs = imfs.lock().unwrap(); + imfs.path_created(&path).unwrap(); } { @@ -34,8 +34,8 @@ fn handle_event(vfs: &Mutex, rbx_session: &Mutex, event: Deboun }, DebouncedEvent::Write(path) => { { - let mut vfs = vfs.lock().unwrap(); - vfs.path_updated(&path).unwrap(); + let mut imfs = imfs.lock().unwrap(); + imfs.path_updated(&path).unwrap(); } { @@ -45,8 +45,8 @@ fn handle_event(vfs: &Mutex, rbx_session: &Mutex, event: Deboun }, DebouncedEvent::Remove(path) => { { - let mut vfs = vfs.lock().unwrap(); - vfs.path_removed(&path).unwrap(); + let mut imfs = imfs.lock().unwrap(); + imfs.path_removed(&path).unwrap(); } { @@ -56,8 +56,8 @@ fn handle_event(vfs: &Mutex, rbx_session: &Mutex, event: Deboun }, DebouncedEvent::Rename(from_path, to_path) => { { - let mut vfs = vfs.lock().unwrap(); - vfs.path_moved(&from_path, &to_path).unwrap(); + let mut imfs = imfs.lock().unwrap(); + imfs.path_moved(&from_path, &to_path).unwrap(); } { @@ -77,13 +77,13 @@ pub struct FsWatcher { } impl FsWatcher { - pub fn start(vfs: Arc>, rbx_session: Arc>) -> FsWatcher { + pub fn start(imfs: Arc>, rbx_session: Arc>) -> FsWatcher { let mut watchers = Vec::new(); { - let vfs_temp = vfs.lock().unwrap(); + let imfs_temp = imfs.lock().unwrap(); - for root_path in vfs_temp.get_roots() { + for root_path in imfs_temp.get_roots() { let (watch_tx, watch_rx) = mpsc::channel(); let mut watcher = notify::watcher(watch_tx, WATCH_TIMEOUT) @@ -94,7 +94,7 @@ impl FsWatcher { watchers.push(watcher); - let vfs = Arc::clone(&vfs); + let imfs = Arc::clone(&imfs); let rbx_session = Arc::clone(&rbx_session); let root_path = root_path.clone(); @@ -102,7 +102,7 @@ impl FsWatcher { info!("Watcher thread ({}) started", root_path.display()); loop { match watch_rx.recv() { - Ok(event) => handle_event(&vfs, &rbx_session, event), + Ok(event) => handle_event(&imfs, &rbx_session, event), Err(_) => break, }; } diff --git a/server/src/vfs.rs b/server/src/imfs.rs similarity index 78% rename from server/src/vfs.rs rename to server/src/imfs.rs index b744d567..519faaaf 100644 --- a/server/src/vfs.rs +++ b/server/src/imfs.rs @@ -5,15 +5,18 @@ use std::{ io, }; +/// The in-memory filesystem keeps a mirror of all files being watcher by Rojo +/// in order to deduplicate file changes in the case of bidirectional syncing +/// from Roblox Studio. #[derive(Debug)] -pub struct Vfs { - items: HashMap, +pub struct Imfs { + items: HashMap, roots: HashSet, } -impl Vfs { - pub fn new() -> Vfs { - Vfs { +impl Imfs { + pub fn new() -> Imfs { + Imfs { items: HashMap::new(), roots: HashSet::new(), } @@ -23,7 +26,7 @@ impl Vfs { &self.roots } - pub fn get(&self, path: &Path) -> Option<&VfsItem> { + pub fn get(&self, path: &Path) -> Option<&ImfsItem> { debug_assert!(path.is_absolute()); debug_assert!(self.is_within_roots(path)); @@ -36,7 +39,7 @@ impl Vfs { self.roots.insert(path.to_path_buf()); - VfsItem::read_from_disk(self, path)?; + ImfsItem::read_from_disk(self, path)?; Ok(()) } @@ -50,7 +53,7 @@ impl Vfs { } } - VfsItem::read_from_disk(self, path)?; + ImfsItem::read_from_disk(self, path)?; Ok(()) } @@ -64,7 +67,7 @@ impl Vfs { } } - VfsItem::read_from_disk(self, path)?; + ImfsItem::read_from_disk(self, path)?; Ok(()) } @@ -74,14 +77,14 @@ impl Vfs { if let Some(parent_path) = path.parent() { if self.is_within_roots(parent_path) { - if let Some(VfsItem::Directory(parent)) = self.items.get_mut(parent_path) { + if let Some(ImfsItem::Directory(parent)) = self.items.get_mut(parent_path) { parent.children.remove(path); } } } match self.items.remove(path) { - Some(VfsItem::Directory(directory)) => { + Some(ImfsItem::Directory(directory)) => { for child_path in &directory.children { self.path_removed(child_path)?; } @@ -115,30 +118,30 @@ impl Vfs { } #[derive(Debug)] -pub struct VfsFile { +pub struct ImfsFile { pub path: PathBuf, pub contents: Vec, } #[derive(Debug)] -pub struct VfsDirectory { +pub struct ImfsDirectory { pub path: PathBuf, pub children: HashSet, } #[derive(Debug)] -pub enum VfsItem { - File(VfsFile), - Directory(VfsDirectory), +pub enum ImfsItem { + File(ImfsFile), + Directory(ImfsDirectory), } -impl VfsItem { - fn read_from_disk<'a, 'b>(vfs: &'a mut Vfs, path: &'b Path) -> io::Result<&'a VfsItem> { +impl ImfsItem { + fn read_from_disk<'a, 'b>(vfs: &'a mut Imfs, path: &'b Path) -> io::Result<&'a ImfsItem> { let metadata = fs::metadata(path)?; if metadata.is_file() { let contents = fs::read(path)?; - let item = VfsItem::File(VfsFile { + let item = ImfsItem::File(ImfsFile { path: path.to_path_buf(), contents, }); @@ -153,12 +156,12 @@ impl VfsItem { let entry = entry?; let child_path = entry.path(); - VfsItem::read_from_disk(vfs, &child_path)?; + ImfsItem::read_from_disk(vfs, &child_path)?; children.insert(child_path); } - let item = VfsItem::Directory(VfsDirectory { + let item = ImfsItem::Directory(ImfsDirectory { path: path.to_path_buf(), children, }); diff --git a/server/src/lib.rs b/server/src/lib.rs index 117aa841..cde3cdb4 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -20,6 +20,6 @@ pub mod project; pub mod rbx_session; pub mod session; pub mod session_id; -pub mod vfs; +pub mod imfs; pub mod web; pub mod web_util; \ No newline at end of file diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index 13d0f7d2..397f949c 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -10,7 +10,7 @@ use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue}; use crate::{ project::{Project, ProjectNode, InstanceProjectNode}, message_queue::MessageQueue, - vfs::{Vfs, VfsItem}, + imfs::{Imfs, ImfsItem}, }; pub struct RbxSession { @@ -18,15 +18,15 @@ pub struct RbxSession { paths_to_ids: HashMap, ids_to_project_paths: HashMap, message_queue: Arc, - vfs: Arc>, + imfs: Arc>, project: Arc, } impl RbxSession { - pub fn new(project: Arc, vfs: Arc>, message_queue: Arc) -> RbxSession { + pub fn new(project: Arc, imfs: Arc>, message_queue: Arc) -> RbxSession { let (tree, paths_to_ids, ids_to_project_paths) = { - let temp_vfs = vfs.lock().unwrap(); - construct_initial_tree(&project, &temp_vfs) + let temp_imfs = imfs.lock().unwrap(); + construct_initial_tree(&project, &temp_imfs) }; RbxSession { @@ -34,7 +34,7 @@ impl RbxSession { paths_to_ids, ids_to_project_paths, message_queue, - vfs, + imfs, project, } } @@ -66,7 +66,7 @@ impl RbxSession { fn construct_initial_tree( project: &Project, - vfs: &Vfs, + imfs: &Imfs, ) -> (RbxTree, HashMap, HashMap) { let paths_to_ids = HashMap::new(); let ids_to_project_paths = HashMap::new(); @@ -80,7 +80,7 @@ fn construct_initial_tree( let mut context = ConstructContext { tree, - vfs, + imfs, paths_to_ids, ids_to_project_paths, }; @@ -98,7 +98,7 @@ fn construct_initial_tree( struct ConstructContext<'a> { tree: RbxTree, - vfs: &'a Vfs, + imfs: &'a Imfs, paths_to_ids: HashMap, ids_to_project_paths: HashMap, } @@ -151,8 +151,8 @@ fn construct_sync_point_node( instance_name: &str, file_path: &Path, ) -> RbxId { - match context.vfs.get(&file_path) { - Some(VfsItem::File(file)) => { + match context.imfs.get(&file_path) { + Some(ImfsItem::File(file)) => { let contents = str::from_utf8(&file.contents).unwrap(); let mut properties = HashMap::new(); @@ -169,7 +169,7 @@ fn construct_sync_point_node( id }, - Some(VfsItem::Directory(directory)) => { + Some(ImfsItem::Directory(directory)) => { let instance = RbxInstance { class_name: "Folder".to_string(), name: instance_name.to_string(), diff --git a/server/src/session.rs b/server/src/session.rs index fd51dd4f..ca237dee 100644 --- a/server/src/session.rs +++ b/server/src/session.rs @@ -6,7 +6,7 @@ use std::{ use crate::{ message_queue::MessageQueue, project::{Project, ProjectNode}, - vfs::Vfs, + imfs::Imfs, session_id::SessionId, rbx_session::RbxSession, fs_watcher::FsWatcher, @@ -20,15 +20,15 @@ pub struct Session { fs_watcher: FsWatcher, } -fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> { +fn add_sync_points(imfs: &mut Imfs, project_node: &ProjectNode) -> io::Result<()> { match project_node { ProjectNode::Instance(node) => { for child in node.children.values() { - add_sync_points(vfs, child)?; + add_sync_points(imfs, child)?; } }, ProjectNode::SyncPoint(node) => { - vfs.add_root(&node.path)?; + imfs.add_root(&node.path)?; }, } @@ -37,23 +37,23 @@ fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> impl Session { pub fn new(project: Project) -> io::Result { - let mut vfs = Vfs::new(); + let mut imfs = Imfs::new(); - add_sync_points(&mut vfs, &project.tree) + add_sync_points(&mut imfs, &project.tree) .expect("Could not add sync points when starting new Rojo session"); - let vfs = Arc::new(Mutex::new(vfs)); + let imfs = Arc::new(Mutex::new(imfs)); let project = Arc::new(project); let message_queue = Arc::new(MessageQueue::new()); let rbx_session = Arc::new(Mutex::new(RbxSession::new( Arc::clone(&project), - Arc::clone(&vfs), + Arc::clone(&imfs), Arc::clone(&message_queue), ))); let fs_watcher = FsWatcher::start( - Arc::clone(&vfs), + Arc::clone(&imfs), Arc::clone(&rbx_session), ); diff --git a/server/tests/read_projects.rs b/server/tests/read_projects.rs index ac9fbd4a..d547e7d0 100644 --- a/server/tests/read_projects.rs +++ b/server/tests/read_projects.rs @@ -22,7 +22,6 @@ fn foo() { let project = Project::load_exact(&project_file_location).unwrap(); assert_eq!(project.name, "foo"); - assert_eq!(project.tree.len(), 1); } #[test] @@ -31,5 +30,4 @@ fn empty() { let project = Project::load_exact(&project_file_location).unwrap(); assert_eq!(project.name, "empty"); - assert_eq!(project.tree.len(), 0); } \ No newline at end of file diff --git a/test-projects/foo.json b/test-projects/foo.json index f12be6a8..e93d066d 100644 --- a/test-projects/foo.json +++ b/test-projects/foo.json @@ -1,6 +1,7 @@ { "name": "foo", "tree": { + "$className": "DataModel", "ReplicatedStorage": { "$className": "ReplicatedStorage", "Rojo": {