mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Refactor ServeSession to support oneshot sessions
- Updated the ServeSession struct to allow for optional ChangeProcessor and related fields, enabling lightweight oneshot sessions that do not require live filesystem monitoring. - Modified the new and new_oneshot methods to initialize sessions accordingly, improving flexibility for commands that only need a snapshot of the tree. - Adjusted related CLI commands to utilize the new oneshot session functionality, enhancing performance for operations like plugin installation and syncback. These changes streamline session management and improve the efficiency of operations that do not require continuous updates.
This commit is contained in:
parent
431b1fb5a5
commit
484b190464
4 changed files with 81 additions and 33 deletions
|
|
@ -55,7 +55,7 @@ fn initialize_plugin() -> anyhow::Result<ServeSession> {
|
||||||
in_memory_fs.load_snapshot("/plugin", plugin_snapshot)?;
|
in_memory_fs.load_snapshot("/plugin", plugin_snapshot)?;
|
||||||
|
|
||||||
let vfs = Vfs::new(in_memory_fs);
|
let vfs = Vfs::new(in_memory_fs);
|
||||||
Ok(ServeSession::new(vfs, "/plugin", None)?)
|
Ok(ServeSession::new_oneshot(vfs, "/plugin")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn install_plugin() -> anyhow::Result<()> {
|
fn install_plugin() -> anyhow::Result<()> {
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ impl SyncbackCommand {
|
||||||
let vfs = Vfs::new_oneshot();
|
let vfs = Vfs::new_oneshot();
|
||||||
|
|
||||||
let project_start_timer = Instant::now();
|
let project_start_timer = Instant::now();
|
||||||
let session_old = ServeSession::new(vfs, path_old.clone(), None)?;
|
let session_old = ServeSession::new_oneshot(vfs, path_old.clone())?;
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Finished opening project in {:0.02}s",
|
"Finished opening project in {:0.02}s",
|
||||||
project_start_timer.elapsed().as_secs_f32()
|
project_start_timer.elapsed().as_secs_f32()
|
||||||
|
|
@ -251,7 +251,7 @@ impl SyncbackCommand {
|
||||||
// cases, we log a warning but don't fail the syncback.
|
// cases, we log a warning but don't fail the syncback.
|
||||||
let sourcemap_path = base_path.join("sourcemap.json");
|
let sourcemap_path = base_path.join("sourcemap.json");
|
||||||
let sourcemap_vfs = Vfs::new_oneshot();
|
let sourcemap_vfs = Vfs::new_oneshot();
|
||||||
match ServeSession::new(sourcemap_vfs, path_old.clone(), None) {
|
match ServeSession::new_oneshot(sourcemap_vfs, path_old.clone()) {
|
||||||
Ok(sourcemap_session) => {
|
Ok(sourcemap_session) => {
|
||||||
write_sourcemap(
|
write_sourcemap(
|
||||||
&sourcemap_session,
|
&sourcemap_session,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ impl UploadCommand {
|
||||||
|
|
||||||
let vfs = Vfs::new_default();
|
let vfs = Vfs::new_default();
|
||||||
|
|
||||||
let session = ServeSession::new(vfs, project_path, None)?;
|
let session = ServeSession::new_oneshot(vfs, project_path)?;
|
||||||
|
|
||||||
let tree = session.tree();
|
let tree = session.tree();
|
||||||
let inner_tree = tree.inner();
|
let inner_tree = tree.inner();
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,12 @@ pub struct ServeSession {
|
||||||
/// before dropping the ChangeProcessor, its thread will panic with a
|
/// before dropping the ChangeProcessor, its thread will panic with a
|
||||||
/// RecvError, causing the main thread to panic on drop.
|
/// RecvError, causing the main thread to panic on drop.
|
||||||
///
|
///
|
||||||
|
/// `None` for oneshot sessions (syncback, upload, plugin install) that
|
||||||
|
/// don't need live filesystem monitoring.
|
||||||
|
///
|
||||||
/// Allowed to be unused because it has side effects when dropped.
|
/// Allowed to be unused because it has side effects when dropped.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
change_processor: ChangeProcessor,
|
change_processor: Option<ChangeProcessor>,
|
||||||
|
|
||||||
/// When the serve session was started. Used only for user-facing
|
/// When the serve session was started. Used only for user-facing
|
||||||
/// diagnostics.
|
/// diagnostics.
|
||||||
|
|
@ -99,22 +102,49 @@ pub struct ServeSession {
|
||||||
|
|
||||||
/// A channel to send mutation requests on. These will be handled by the
|
/// A channel to send mutation requests on. These will be handled by the
|
||||||
/// ChangeProcessor and trigger changes in the tree.
|
/// ChangeProcessor and trigger changes in the tree.
|
||||||
tree_mutation_sender: Sender<PatchSet>,
|
/// `None` for oneshot sessions.
|
||||||
|
tree_mutation_sender: Option<Sender<PatchSet>>,
|
||||||
|
|
||||||
/// Paths recently written by the API's syncback. The ChangeProcessor
|
/// Paths recently written by the API's syncback. The ChangeProcessor
|
||||||
/// checks this map and suppresses the file watcher echo for these paths
|
/// checks this map and suppresses the file watcher echo for these paths
|
||||||
/// to avoid redundant re-snapshots and WebSocket messages.
|
/// to avoid redundant re-snapshots and WebSocket messages.
|
||||||
/// Values are `(remove_count, create_write_count)` — each API write increments
|
/// Values are `(remove_count, create_write_count)` — each API write increments
|
||||||
/// the appropriate counter, each suppressed VFS event decrements it.
|
/// the appropriate counter, each suppressed VFS event decrements it.
|
||||||
|
/// `None` for oneshot sessions.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
suppressed_paths: Arc<Mutex<std::collections::HashMap<std::path::PathBuf, (usize, usize)>>>,
|
suppressed_paths:
|
||||||
|
Option<Arc<Mutex<std::collections::HashMap<std::path::PathBuf, (usize, usize)>>>>,
|
||||||
|
|
||||||
/// Index of meta/model files that contain `Rojo_Ref_*` attributes.
|
/// Index of meta/model files that contain `Rojo_Ref_*` attributes.
|
||||||
/// Shared between ApiService (writes) and ChangeProcessor (rename updates).
|
/// Shared between ApiService (writes) and ChangeProcessor (rename updates).
|
||||||
ref_path_index: Arc<Mutex<crate::RefPathIndex>>,
|
/// `None` for oneshot sessions.
|
||||||
|
ref_path_index: Option<Arc<Mutex<crate::RefPathIndex>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServeSession {
|
impl ServeSession {
|
||||||
|
/// Shared initialization: loads the project and builds the initial
|
||||||
|
/// snapshot tree. Used by both `new()` and `new_oneshot()`.
|
||||||
|
fn init_tree(vfs: &Vfs, start_path: &Path) -> Result<(Project, RojoTree), ServeSessionError> {
|
||||||
|
log::trace!("Starting new ServeSession at path {}", start_path.display());
|
||||||
|
|
||||||
|
let root_project = Project::load_initial_project(vfs, start_path)?;
|
||||||
|
|
||||||
|
let mut tree = RojoTree::new(InstanceSnapshot::new());
|
||||||
|
let root_id = tree.get_root_id();
|
||||||
|
let instance_context = InstanceContext::new();
|
||||||
|
|
||||||
|
log::trace!("Generating snapshot of instances from VFS");
|
||||||
|
let snapshot = snapshot_from_vfs(&instance_context, vfs, start_path)?;
|
||||||
|
|
||||||
|
log::trace!("Computing initial patch set");
|
||||||
|
let patch_set = compute_patch_set(snapshot, &tree, root_id);
|
||||||
|
|
||||||
|
log::trace!("Applying initial patch set");
|
||||||
|
apply_patch_set(&mut tree, patch_set);
|
||||||
|
|
||||||
|
Ok((root_project, tree))
|
||||||
|
}
|
||||||
|
|
||||||
/// Start a new serve session from the given in-memory filesystem and start
|
/// Start a new serve session from the given in-memory filesystem and start
|
||||||
/// path.
|
/// path.
|
||||||
///
|
///
|
||||||
|
|
@ -129,24 +159,7 @@ impl ServeSession {
|
||||||
let start_path = start_path.as_ref();
|
let start_path = start_path.as_ref();
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
|
|
||||||
log::trace!("Starting new ServeSession at path {}", start_path.display());
|
let (root_project, tree) = Self::init_tree(&vfs, start_path)?;
|
||||||
|
|
||||||
let root_project = Project::load_initial_project(&vfs, start_path)?;
|
|
||||||
|
|
||||||
let mut tree = RojoTree::new(InstanceSnapshot::new());
|
|
||||||
|
|
||||||
let root_id = tree.get_root_id();
|
|
||||||
|
|
||||||
let instance_context = InstanceContext::new();
|
|
||||||
|
|
||||||
log::trace!("Generating snapshot of instances from VFS");
|
|
||||||
let snapshot = snapshot_from_vfs(&instance_context, &vfs, start_path)?;
|
|
||||||
|
|
||||||
log::trace!("Computing initial patch set");
|
|
||||||
let patch_set = compute_patch_set(snapshot, &tree, root_id);
|
|
||||||
|
|
||||||
log::trace!("Applying initial patch set");
|
|
||||||
apply_patch_set(&mut tree, patch_set);
|
|
||||||
|
|
||||||
let session_id = SessionId::new();
|
let session_id = SessionId::new();
|
||||||
let message_queue = MessageQueue::new();
|
let message_queue = MessageQueue::new();
|
||||||
|
|
@ -172,16 +185,41 @@ impl ServeSession {
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
change_processor,
|
change_processor: Some(change_processor),
|
||||||
start_time,
|
start_time,
|
||||||
session_id,
|
session_id,
|
||||||
root_project,
|
root_project,
|
||||||
tree,
|
tree,
|
||||||
message_queue,
|
message_queue,
|
||||||
tree_mutation_sender,
|
tree_mutation_sender: Some(tree_mutation_sender),
|
||||||
vfs,
|
vfs,
|
||||||
suppressed_paths,
|
suppressed_paths: Some(suppressed_paths),
|
||||||
ref_path_index,
|
ref_path_index: Some(ref_path_index),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a lightweight oneshot session that builds the project tree
|
||||||
|
/// but does NOT start a ChangeProcessor thread or filesystem watcher.
|
||||||
|
///
|
||||||
|
/// Use this for commands that only need a snapshot of the tree and
|
||||||
|
/// don't require live updates (syncback, upload, plugin install).
|
||||||
|
pub fn new_oneshot<P: AsRef<Path>>(vfs: Vfs, start_path: P) -> Result<Self, ServeSessionError> {
|
||||||
|
let start_path = start_path.as_ref();
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
|
let (root_project, tree) = Self::init_tree(&vfs, start_path)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
change_processor: None,
|
||||||
|
start_time,
|
||||||
|
session_id: SessionId::new(),
|
||||||
|
root_project,
|
||||||
|
tree: Arc::new(Mutex::new(tree)),
|
||||||
|
message_queue: Arc::new(MessageQueue::new()),
|
||||||
|
tree_mutation_sender: None,
|
||||||
|
vfs: Arc::new(vfs),
|
||||||
|
suppressed_paths: None,
|
||||||
|
ref_path_index: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,7 +232,9 @@ impl ServeSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tree_mutation_sender(&self) -> Sender<PatchSet> {
|
pub fn tree_mutation_sender(&self) -> Sender<PatchSet> {
|
||||||
self.tree_mutation_sender.clone()
|
self.tree_mutation_sender
|
||||||
|
.clone()
|
||||||
|
.expect("tree_mutation_sender is not available on oneshot sessions")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a handle to the suppressed paths map, used to avoid
|
/// Returns a handle to the suppressed paths map, used to avoid
|
||||||
|
|
@ -203,13 +243,21 @@ impl ServeSession {
|
||||||
pub fn suppressed_paths(
|
pub fn suppressed_paths(
|
||||||
&self,
|
&self,
|
||||||
) -> Arc<Mutex<std::collections::HashMap<std::path::PathBuf, (usize, usize)>>> {
|
) -> Arc<Mutex<std::collections::HashMap<std::path::PathBuf, (usize, usize)>>> {
|
||||||
Arc::clone(&self.suppressed_paths)
|
Arc::clone(
|
||||||
|
self.suppressed_paths
|
||||||
|
.as_ref()
|
||||||
|
.expect("suppressed_paths is not available on oneshot sessions"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a handle to the Ref path index, shared between ApiService
|
/// Returns a handle to the Ref path index, shared between ApiService
|
||||||
/// and ChangeProcessor for efficient rename path updates.
|
/// and ChangeProcessor for efficient rename path updates.
|
||||||
pub fn ref_path_index(&self) -> Arc<Mutex<crate::RefPathIndex>> {
|
pub fn ref_path_index(&self) -> Arc<Mutex<crate::RefPathIndex>> {
|
||||||
Arc::clone(&self.ref_path_index)
|
Arc::clone(
|
||||||
|
self.ref_path_index
|
||||||
|
.as_ref()
|
||||||
|
.expect("ref_path_index is not available on oneshot sessions"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue