Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add *.md support for plugin's details #2204

Open
wants to merge 7 commits into
base: plugins_support
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::{
path::{Path, PathBuf},
};

use stypes::{InvalidPluginEntity, PluginMetadata};
use stypes::{
ExtendedInvalidPluginEntity, ExtendedPluginEntity, InvalidPluginEntity, PluginMetadata,
PluginRunData,
};

use crate::{
plugins_shared::plugin_errors::PluginError, PluginHostInitError, PluginType, PluginsByteSource,
Expand All @@ -20,8 +23,8 @@ use super::{InitError, PluginEntity};
/// # Returns:
///
/// List of valid plugins alongside with other list for invalid ones.
pub async fn load_all_plugins() -> Result<(Vec<PluginEntity>, Vec<InvalidPluginEntity>), InitError>
{
pub async fn load_all_plugins(
) -> Result<(Vec<ExtendedPluginEntity>, Vec<ExtendedInvalidPluginEntity>), InitError> {
let plugins_dir = paths::plugins_dir()?;
if !plugins_dir.exists() {
log::trace!("Plugins directory doesn't exist. Creating it...");
Expand All @@ -45,7 +48,7 @@ pub async fn load_all_plugins() -> Result<(Vec<PluginEntity>, Vec<InvalidPluginE
/// List of valid plugins alongside with other list for invalid ones.
async fn load_plugins(
plug_type: PluginType,
) -> Result<(Vec<PluginEntity>, Vec<InvalidPluginEntity>), InitError> {
) -> Result<(Vec<ExtendedPluginEntity>, Vec<ExtendedInvalidPluginEntity>), InitError> {
let mut valid_plugins = Vec::new();
let mut invalid_plugins = Vec::new();

Expand Down Expand Up @@ -74,8 +77,8 @@ async fn load_plugins(
/// Represents the various states of a plugin entity.
/// This type is used internally in this module only.
enum PluginEntityState {
Valid(PluginEntity),
Invalid(InvalidPluginEntity),
Valid(ExtendedPluginEntity),
Invalid(ExtendedInvalidPluginEntity),
}

/// Loads plugin infos and metadata from the provided plugin directory.
Expand All @@ -90,19 +93,24 @@ async fn load_plugin(
plug_dir: PathBuf,
plug_type: PluginType,
) -> Result<PluginEntityState, InitError> {
let mut rd = PluginRunData::default();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the names to be more expressive. Can we change this to run_data or rdata

rd.info("Attempt to load and check plugin");
let (wasm_file, metadata_file) = match validate_plugin_files(&plug_dir)? {
PluginValidationState::Valid {
wasm_path: wasm,
metadata,
} => (wasm, metadata),
PluginValidationState::Invalid { err_msg } => {
let invalid_entity = InvalidPluginEntity {
dir_path: plug_dir,
plugin_type: plug_type,
error_msgs: vec![err_msg],
};

return Ok(PluginEntityState::Invalid(invalid_entity));
rd.err(err_msg);
return Ok(PluginEntityState::Invalid(
ExtendedInvalidPluginEntity::new(
InvalidPluginEntity {
dir_path: plug_dir,
plugin_type: plug_type,
},
rd,
),
));
}
};

Expand All @@ -118,29 +126,33 @@ async fn load_plugin(
return Err(err.into())
}
Err(err) => {
let err_msg = format!("Loading plugin binary fail. Error: {err}");
let invalid = InvalidPluginEntity {
dir_path: plug_dir,
plugin_type: plug_type,
error_msgs: vec![err_msg],
};

return Ok(PluginEntityState::Invalid(invalid));
rd.err(format!("Loading plugin binary fail. Error: {err}"));
return Ok(PluginEntityState::Invalid(
ExtendedInvalidPluginEntity::new(
InvalidPluginEntity {
dir_path: plug_dir,
plugin_type: plug_type,
},
rd,
),
));
}
};

let mut warn_msgs = Vec::new();
let plug_metadata = match metadata_file {
Some(file) => match parse_metadata(&file) {
Ok(metadata) => metadata,
Ok(metadata) => {
rd.info("Metadata file found and load");
metadata
}
Err(err_msg) => {
warn_msgs.push(format!(
rd.err(format!(
"Parsing metadata file failed with error: {err_msg}"
));
let dir_name = plug_dir
.file_name()
.and_then(|p| p.to_str())
.unwrap_or("Unkown");
.unwrap_or("Unknown");

PluginMetadata {
name: dir_name.into(),
Expand All @@ -149,28 +161,28 @@ async fn load_plugin(
}
},
None => {
warn_msgs.push(String::from("Metadata file not found"));
rd.warn("Metadata file not found");
let dir_name = plug_dir
.file_name()
.and_then(|p| p.to_str())
.unwrap_or("Unkown");
.unwrap_or("Unknown");

PluginMetadata {
name: dir_name.into(),
description: None,
}
}
};

let valid_plugin = PluginEntity {
dir_path: plug_dir,
plugin_type: plug_type,
info: plug_info,
metadata: plug_metadata,
warn_msgs,
};

Ok(PluginEntityState::Valid(valid_plugin))
rd.info("Plugin has been load, checked and accepted");
Ok(PluginEntityState::Valid(ExtendedPluginEntity::new(
PluginEntity {
dir_path: plug_dir,
plugin_type: plug_type,
info: plug_info,
metadata: plug_metadata,
},
rd,
)))
}

/// Retrieves all directory form the given directory path
Expand Down
77 changes: 63 additions & 14 deletions application/apps/indexer/plugins_host/src/plugins_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ mod tests;
use std::path::{Path, PathBuf};

pub use errors::InitError;
use stypes::{InvalidPluginEntity, PluginEntity};
use stypes::{
ExtendedInvalidPluginEntity, ExtendedPluginEntity, InvalidPluginEntity, PluginEntity,
PluginRunData,
};

/// Plugins manager responsible of loading the plugins, providing their states, info and metadata.
#[derive(Debug)]
pub struct PluginsManager {
installed_plugins: Vec<PluginEntity>,
invalid_plugins: Vec<InvalidPluginEntity>,
installed_plugins: Vec<ExtendedPluginEntity>,
invalid_plugins: Vec<ExtendedInvalidPluginEntity>,
}

impl PluginsManager {
Expand All @@ -30,41 +33,87 @@ impl PluginsManager {
}

/// Provide full infos of all loaded and valid plugins.
pub fn installed_plugins(&self) -> &[PluginEntity] {
&self.installed_plugins
pub fn installed_plugins(&self) -> Vec<&PluginEntity> {
self.installed_plugins
.iter()
.map(|en| en.into())
.collect::<Vec<&PluginEntity>>()
Comment on lines -33 to +40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can return an iterator here without having to collect into vector inside the function

    /// Provide full infos of all loaded and valid plugins.
    pub fn installed_plugins(&self) -> impl Iterator<Item = &PluginEntity> {
        self.installed_plugins.iter().map(|en| en.into())
    }

}

/// Provide directory paths (considered ID) of all loaded and valid plugins.
pub fn installed_plugins_paths(&self) -> impl Iterator<Item = &PathBuf> {
self.installed_plugins.iter().map(|p| &p.dir_path)
self.installed_plugins.iter().map(|p| &p.entity.dir_path)
}

/// Provide the info of the plugin with the given [`plugin_dir`] if available.
///
/// * `plugin_dir`: The directory path of the plugin. Considered as ID currently.
pub fn get_installed_plugin(&self, plugin_dir: &Path) -> Option<&PluginEntity> {
self.installed_plugins
.iter()
.find(|p| p.dir_path == plugin_dir)
self.installed_plugins.iter().find_map(|p| {
if p.entity.dir_path == plugin_dir {
Some(p.into())
} else {
None
}
})
}

/// Provide all invalid plugins.
pub fn invalid_plugins(&self) -> &[InvalidPluginEntity] {
&self.invalid_plugins
pub fn invalid_plugins(&self) -> Vec<&InvalidPluginEntity> {
self.invalid_plugins
.iter()
.map(|en| en.into())
.collect::<Vec<&InvalidPluginEntity>>()
Comment on lines -52 to +66
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning an iterator is more flexible here as well

    pub fn invalid_plugins(&self) -> impl Iterator<Item = &InvalidPluginEntity> {
        self.invalid_plugins.iter().map(|en| en.into())
    }

}

/// Provide directory paths (considered ID) of all invalid plugins.
pub fn invalid_plugins_paths(&self) -> impl Iterator<Item = &PathBuf> {
self.invalid_plugins.iter().map(|p| &p.dir_path)
self.invalid_plugins.iter().map(|p| &p.entity.dir_path)
}

/// Provide the info of the invalid plugin with the given [`plugin_dir`] if available.
///
/// * `plugin_dir`: The directory path of the plugin. Considered as ID currently.
pub fn get_invalid_plugin(&self, plugin_dir: &Path) -> Option<&InvalidPluginEntity> {
self.invalid_plugins
self.invalid_plugins.iter().find_map(|p| {
if p.entity.dir_path == plugin_dir {
Some(p.into())
} else {
None
}
})
}

/// Retrieves runtime data for a plugin located at the specified path.
///
/// This method searches for the plugin's runtime data (`PluginRunData`) among both
/// successfully loaded plugins and failed ones.
///
/// # Parameters
/// - `plugin_dir`: The directory path of the plugin.
///
/// # Returns
/// - `Some(&PluginRunData)`: If the plugin's runtime data is found.
/// - `None`: If no matching plugin is found.
pub fn get_plugin_run_data<P: AsRef<Path>>(&self, plugin_dir: P) -> Option<&PluginRunData> {
self.installed_plugins
.iter()
.find(|p| p.dir_path == plugin_dir)
.find_map(|p| {
if p.entity.dir_path == plugin_dir.as_ref() {
Some(&p.rd)
} else {
None
}
})
.or_else(|| {
self.invalid_plugins.iter().find_map(|p| {
if p.entity.dir_path == plugin_dir.as_ref() {
Some(&p.rd)
} else {
None
}
})
})
}

/// Reload all the plugins from the plugins directory.
Expand Down
30 changes: 16 additions & 14 deletions application/apps/indexer/plugins_host/src/plugins_manager/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const INV_SOURCE_PATH: &str = "inv_soruce";

/// Provide manager mock to test it's API
fn create_manager() -> PluginsManager {
let installed_plugins = vec![
let installed_plugins: Vec<ExtendedPluginEntity> = vec![
PluginEntity {
dir_path: PARSER_PATH_1.into(),
plugin_type: PluginType::Parser,
Expand All @@ -31,8 +31,8 @@ fn create_manager() -> PluginsManager {
name: "parser_1".into(),
description: None,
},
warn_msgs: Vec::new(),
},
}
.into(),
PluginEntity {
dir_path: PARSER_PATH_2.into(),
plugin_type: PluginType::Parser,
Expand All @@ -49,8 +49,8 @@ fn create_manager() -> PluginsManager {
name: "parser_2".into(),
description: None,
},
warn_msgs: Vec::new(),
},
}
.into(),
PluginEntity {
dir_path: SOURCE_PATH_1.into(),
plugin_type: PluginType::ByteSource,
Expand All @@ -65,8 +65,8 @@ fn create_manager() -> PluginsManager {
name: "source_1".into(),
description: None,
},
warn_msgs: Vec::new(),
},
}
.into(),
PluginEntity {
dir_path: SOURCE_PATH_2.into(),
plugin_type: PluginType::ByteSource,
Expand All @@ -81,22 +81,24 @@ fn create_manager() -> PluginsManager {
name: "source_2".into(),
description: None,
},
warn_msgs: Vec::new(),
},
}
.into(),
];

let invalid_plugins = vec![
let mut invalid_plugins: Vec<ExtendedInvalidPluginEntity> = vec![
InvalidPluginEntity {
dir_path: INV_PARSER_PATH.into(),
plugin_type: PluginType::Parser,
error_msgs: vec![String::from("error")],
},
}
.into(),
InvalidPluginEntity {
dir_path: INV_SOURCE_PATH.into(),
plugin_type: PluginType::ByteSource,
error_msgs: vec![String::from("error")],
},
}
.into(),
];
invalid_plugins[0].rd.err("error");
invalid_plugins[1].rd.err("error");

PluginsManager {
installed_plugins,
Expand Down
16 changes: 16 additions & 0 deletions application/apps/indexer/session/src/unbound/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,22 @@ impl UnboundSessionAPI {
.await
}

/// Retrieves runtime data for a plugin located at the specified path.
pub async fn get_plugin_run_data(
&self,
id: u64,
plugin_path: String,
) -> Result<stypes::CommandOutcome<Option<stypes::PluginRunData>>, stypes::ComputationError>
{
let (tx_results, rx_results) = oneshot::channel();
self.process_command(
id,
rx_results,
Command::PluginRunData(plugin_path, tx_results),
)
.await
}

/// Reload the plugin directory.
pub async fn reload_plugins(
&self,
Expand Down
Loading
Loading