use crate::config::PluginConfig;
use crate::error::{PluginManagerError, PluginManagerResult};
use crate::status::PluginStatus;
use crate::manager::types::{PluginInstance, PluginMap};
use crate::manager::loader::{load_plugin, scan_plugin_directory};
use crate::manager::validation::sanitize_plugin_name;
use std::path::Path;
use tracing::{debug, error, info, trace, warn};
use tracing_shared::SharedLogger;
pub async fn load_all_plugins(
plugins: PluginMap,
plugin_dir: &str,
temp_dir: &str,
ed25519_public_key_path: Option<String>,
rsa_private_key_path: Option<String>,
library_path: Option<&String>,
) -> PluginManagerResult<()> {
trace!("开始批量加载插件 - 目录: {}, 临时目录: {}", plugin_dir, temp_dir);
info!("开始加载插件...");
debug!("步骤 1: 清空并创建临时目录");
info!("清空插件临时目录: {}", temp_dir);
if Path::new(temp_dir).exists() {
trace!("临时目录已存在,删除: {}", temp_dir);
tokio::fs::remove_dir_all(temp_dir).await?;
}
tokio::fs::create_dir_all(temp_dir).await?;
debug!("临时目录创建成功");
if !Path::new(plugin_dir).exists() {
warn!("插件目录不存在: {}", plugin_dir);
return Ok(());
}
trace!("插件目录存在: {}", plugin_dir);
debug!("步骤 2: 扫描插件目录");
let plugin_files = scan_plugin_directory(plugin_dir).await?;
if plugin_files.is_empty() {
info!("未找到任何插件文件");
return Ok(());
} else {
info!("发现 {} 个插件文件", plugin_files.len());
debug!("插件文件列表: {:?}", plugin_files);
}
debug!("步骤 3: 逐个加载插件");
let mut child_instances: Vec<PluginInstance> = Vec::new();
let mut success_count = 0;
let mut failure_count = 0;
let logger = SharedLogger::new();
for plugin_file in plugin_files {
trace!("开始加载插件文件: {}", plugin_file);
match load_plugin(
&plugin_file,
ed25519_public_key_path.clone(),
rsa_private_key_path.clone(),
temp_dir,
library_path,
logger.clone()
)
.await
{
Ok(instance) => {
debug!("插件加载成功: {} (ID: {})",
instance.metadata.name, instance.metadata.id);
if instance.metadata.is_sub_plugin {
trace!("检测到子插件,暂存: {}", instance.metadata.id);
child_instances.push(instance);
} else if let Err(e) = insert_plugin_instance(
plugins.clone(),
instance,
).await {
error!("保存插件实例失败 {}: {}", plugin_file, e);
failure_count += 1;
} else {
success_count += 1;
}
}
Err(e) => {
error!("插件加载失败: {} - {}", plugin_file, e);
failure_count += 1;
}
}
}
debug!("步骤 4: 挂载子插件 (共 {} 个)", child_instances.len());
for child_instance in child_instances {
trace!("挂载子插件: {}", child_instance.metadata.id);
if let Err(e) = insert_child_plugin(
plugins.clone(),
child_instance,
).await {
error!("子插件挂载失败: {}", e);
failure_count += 1;
} else {
success_count += 1;
}
}
info!("插件加载完成 - 成功: {}, 失败: {}, 总计: {}",
success_count, failure_count, success_count + failure_count);
trace!("批量加载插件流程完成");
Ok(())
}
pub async fn insert_plugin_instance(
plugins: PluginMap,
plugin_instance: PluginInstance,
) -> PluginManagerResult<()> {
let plugin_id = plugin_instance.metadata.id.clone();
let plugin_name = plugin_instance.metadata.name.clone();
let plugin_version = plugin_instance.metadata.version.clone();
let fingerprint = plugin_instance.fingerprint.clone();
trace!("准备插入插件实例: {} ({})", plugin_name, plugin_id);
let span = tracing::info_span!(
"plugin_insert",
plugin_id = %plugin_id,
fingerprint = %fingerprint,
plugin_version = %plugin_version
);
let _guard = span.enter();
{
debug!("获取写锁,插入插件实例");
let mut plugins = plugins.write().await;
plugins.insert(plugin_id.clone(), plugin_instance);
trace!("插件实例已插入到映射表");
}
info!(
plugin_id = %plugin_id,
fingerprint = %fingerprint,
plugin_version = %plugin_version,
"插件加载成功: {} ({}) v{}",
plugin_name, plugin_id, plugin_version
);
debug!("插件实例插入完成");
Ok(())
}
pub async fn insert_child_plugin(
plugins: PluginMap,
plugin_instance: PluginInstance,
) -> PluginManagerResult<()> {
let child_id = plugin_instance.metadata.id.clone();
let child_name = plugin_instance.metadata.name.clone();
let child_version = plugin_instance.metadata.version.clone();
trace!("准备挂载子插件: {} -> 父插件", child_id);
let parent_id = plugin_instance
.metadata
.parent_plugin_id
.as_ref()
.ok_or_else(|| {
error!("子插件 {} 未配置父插件 ID", child_id);
PluginManagerError::Other(format!("子插件 {} 未配置父插件 ID", child_id))
})?
.clone();
debug!("子插件 {} 的父插件: {}", child_id, parent_id);
let child_info = crate::status::ChildPluginInfo::from_metadata(&plugin_instance.metadata);
{
debug!("获取写锁,挂载子插件到父插件");
let mut plugins = plugins.write().await;
if let Some(parent) = plugins.get_mut(&parent_id) {
trace!("找到父插件,添加子插件信息");
parent.child_plugins.push(child_info);
} else {
error!("未找到父插件 {},无法挂载子插件 {}", parent_id, child_id);
return Err(PluginManagerError::not_found(format!(
"未找到父插件 {},无法挂载子插件 {}",
parent_id, child_id
)));
}
plugins.insert(child_id.clone(), plugin_instance);
trace!("子插件实例已插入到映射表");
}
info!(
"子插件加载成功: {} ({}) v{} -> 父插件 {}",
child_name, child_id, child_version, parent_id
);
debug!("子插件挂载完成");
Ok(())
}