Vfs -> Imfs, clean up and document a bit

This commit is contained in:
Lucien Greathouse
2018-11-17 13:51:22 -08:00
parent c8bb9bf2e9
commit 16c3c1f498
9 changed files with 67 additions and 66 deletions

10
server/Cargo.lock generated
View File

@@ -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"

View File

@@ -35,3 +35,4 @@ uuid = { version = "0.7", features = ["v4", "serde"] }
[dev-dependencies]
tempfile = "3.0"
walkdir = "2.1"
lazy_static = "1.2"

View File

@@ -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<Vfs>, rbx_session: &Mutex<RbxSession>, event: DebouncedEvent) {
fn handle_event(imfs: &Mutex<Imfs>, rbx_session: &Mutex<RbxSession>, 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<Vfs>, rbx_session: &Mutex<RbxSession>, 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<Vfs>, rbx_session: &Mutex<RbxSession>, 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<Vfs>, rbx_session: &Mutex<RbxSession>, 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<Mutex<Vfs>>, rbx_session: Arc<Mutex<RbxSession>>) -> FsWatcher {
pub fn start(imfs: Arc<Mutex<Imfs>>, rbx_session: Arc<Mutex<RbxSession>>) -> 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,
};
}

View File

@@ -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<PathBuf, VfsItem>,
pub struct Imfs {
items: HashMap<PathBuf, ImfsItem>,
roots: HashSet<PathBuf>,
}
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<u8>,
}
#[derive(Debug)]
pub struct VfsDirectory {
pub struct ImfsDirectory {
pub path: PathBuf,
pub children: HashSet<PathBuf>,
}
#[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,
});

View File

@@ -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;

View File

@@ -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<PathBuf, RbxId>,
ids_to_project_paths: HashMap<RbxId, String>,
message_queue: Arc<MessageQueue>,
vfs: Arc<Mutex<Vfs>>,
imfs: Arc<Mutex<Imfs>>,
project: Arc<Project>,
}
impl RbxSession {
pub fn new(project: Arc<Project>, vfs: Arc<Mutex<Vfs>>, message_queue: Arc<MessageQueue>) -> RbxSession {
pub fn new(project: Arc<Project>, imfs: Arc<Mutex<Imfs>>, message_queue: Arc<MessageQueue>) -> 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<PathBuf, RbxId>, HashMap<RbxId, String>) {
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<PathBuf, RbxId>,
ids_to_project_paths: HashMap<RbxId, String>,
}
@@ -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(),

View File

@@ -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<Session> {
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),
);

View File

@@ -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);
}

View File

@@ -1,6 +1,7 @@
{
"name": "foo",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"Rojo": {