From 7077f0f1f382534bd6e2b49a3d3e3a114da4fc9f Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Sat, 12 Oct 2019 23:27:12 -0700 Subject: [PATCH] Load user plugins on startup instead of lazily at snapshot time --- src/common_setup.rs | 3 +- src/snapshot_middleware/context.rs | 48 ++++++++++++++++++------- src/snapshot_middleware/user_plugins.rs | 48 +------------------------ 3 files changed, 37 insertions(+), 62 deletions(-) diff --git a/src/common_setup.rs b/src/common_setup.rs index d21a07d9..50734117 100644 --- a/src/common_setup.rs +++ b/src/common_setup.rs @@ -41,8 +41,7 @@ pub fn start( // If the project file defines no plugins, then there's no need to // initialize the snapshot plugin context. if !project.plugins.is_empty() { - snapshot_context.plugin_context = - Some(SnapshotPluginContext::new(project.plugins.clone())); + snapshot_context.plugin_context = Some(SnapshotPluginContext::new(&project.plugins)); } } diff --git a/src/snapshot_middleware/context.rs b/src/snapshot_middleware/context.rs index ba376085..b125b890 100644 --- a/src/snapshot_middleware/context.rs +++ b/src/snapshot_middleware/context.rs @@ -1,7 +1,9 @@ -use std::{fmt, ops::Deref, path::PathBuf}; +use std::{fmt, fs, ops::Deref, path::Path}; use rlua::{Lua, RegistryKey}; +use super::error::SnapshotError; + #[derive(Debug)] pub struct InstanceSnapshotContext { /// Holds all the state needed to run user plugins as part of the snapshot @@ -23,22 +25,42 @@ impl Default for InstanceSnapshotContext { pub struct SnapshotPluginContext { pub state: IgnoreDebug, - /// Paths to the user plugins files. These paths are generated by the root - /// project file, if there is one. - pub plugin_paths: Vec, - - /// Lazy-initialized registry keys pointing to the values returned by each - /// user plugin. When processing user plugins, these should be applied in - /// order. - pub plugin_functions: Option>, + /// Registry keys pointing to the values returned by each user plugin. When + /// processing user plugins, these should be applied in order. + pub plugin_functions: Vec, } impl SnapshotPluginContext { - pub fn new(plugin_paths: Vec) -> Self { + pub fn new>(plugin_paths: &[P]) -> Self { + let lua_state = Lua::new(); + + let plugin_functions = plugin_paths + .iter() + .map(|path| { + let path = path.as_ref(); + + let content = + fs::read_to_string(path).map_err(|err| SnapshotError::wrap(err, path))?; + + lua_state.context(|lua_context| { + // Plugins are currently expected to return a function that will + // be run when a snapshot needs to be generated. + let result = lua_context + .load(&content) + .set_name(&path.display().to_string())? + .call::<_, rlua::Function>(())?; + + let key = lua_context.create_registry_value(result)?; + + Ok(key) + }) + }) + .collect::, SnapshotError>>() + .expect("Plugin initialization error"); + Self { - state: IgnoreDebug(Lua::new()), - plugin_paths, - plugin_functions: None, + state: IgnoreDebug(lua_state), + plugin_functions, } } } diff --git a/src/snapshot_middleware/user_plugins.rs b/src/snapshot_middleware/user_plugins.rs index 6e4627ce..f39d9336 100644 --- a/src/snapshot_middleware/user_plugins.rs +++ b/src/snapshot_middleware/user_plugins.rs @@ -1,12 +1,7 @@ -use std::{fs, path::Path}; - -use rlua::{Lua, RegistryKey}; - use crate::vfs::{Vfs, VfsEntry, VfsFetcher}; use super::{ context::InstanceSnapshotContext, - error::SnapshotError, middleware::{SnapshotInstanceResult, SnapshotMiddleware}, }; @@ -30,23 +25,9 @@ impl SnapshotMiddleware for SnapshotUserPlugins { None => return Ok(None), }; - // If the plugins listed for use haven't been loaded yet, read them into - // memory, run them, and keep the result they return as a registry key - // into our Lua state. - let keys = match &plugin_context.plugin_functions { - Some(keys) => keys, - None => { - plugin_context.plugin_functions = Some(initialize_plugins( - &plugin_context.state, - &plugin_context.plugin_paths, - )?); - plugin_context.plugin_functions.as_ref().unwrap() - } - }; - plugin_context.state.context(|lua_context| { lua_context.scope(|_scope| { - for _key in keys { + for _key in &plugin_context.plugin_functions { // TODO: Invoke plugin here and get result out. // The current plan for plugins here is to make them work @@ -85,30 +66,3 @@ impl SnapshotMiddleware for SnapshotUserPlugins { Ok(None) } } - -fn initialize_plugins>( - lua_state: &Lua, - plugin_paths: &[P], -) -> Result, SnapshotError> { - plugin_paths - .iter() - .map(|path| { - let path = path.as_ref(); - - let content = fs::read_to_string(path).map_err(|err| SnapshotError::wrap(err, path))?; - - lua_state.context(|lua_context| { - // Plugins are currently expected to return a function that will - // be run when a snapshot needs to be generated. - let result = lua_context - .load(&content) - .set_name(&path.display().to_string())? - .call::<_, rlua::Function>(())?; - - let key = lua_context.create_registry_value(result)?; - - Ok(key) - }) - }) - .collect::, _>>() -}