use crate::error::{PluginManagerError, PluginManagerResult};
use crate::status::PluginStatus;
use crate::manager::types::{PluginInstance, PluginMap};
use crate::manager::validation::sanitize_plugin_name;
use tokio::time::{timeout, Duration};
use tracing::{debug, error, info, trace, warn};
pub async fn start_all_plugins(
plugins: PluginMap,
timeout_secs: u64,
) -> PluginManagerResult<()> {
trace!("开始批量启动插件,超时时间: {}s", timeout_secs);
info!("开始启动插件...");
let start_order = {
trace!("获取读锁,查找需要启动的插件");
let plugins = plugins.read().await;
let mut start_ids = Vec::new();
let mut child_ids = Vec::new();
for (id, instance) in plugins.iter() {
if instance.status == PluginStatus::Initialized {
if instance.metadata.is_sub_plugin {
trace!("发现需要启动的子插件: {}", id);
child_ids.push(id.to_string());
} else {
trace!("发现需要启动的主插件: {}", id);
start_ids.push(id.to_string());
}
}
}
let child_count = child_ids.len();
start_ids.extend(child_ids);
debug!("需要启动的插件: {} 个主插件, {} 个子插件",
start_ids.len() - child_count, child_count);
start_ids
};
let mut success_count = 0;
let mut failure_count = 0;
for plugin_id in start_order {
trace!("启动插件: {}", plugin_id);
let mut plugins = plugins.write().await;
if let Some(plugin_instance) = plugins.get_mut(&plugin_id) {
if plugin_instance.status == PluginStatus::Initialized {
debug!("调用插件 start 方法: {}", plugin_id);
let start_result = timeout(
Duration::from_secs(timeout_secs),
plugin_instance.plugin.start()
).await;
match start_result {
Ok(Ok(_)) => {
if plugin_instance.status.validate_transition(&PluginStatus::Running).is_ok() {
plugin_instance.status = PluginStatus::Running;
info!("插件启动成功: {}", plugin_id);
success_count += 1;
} else {
plugin_instance.status = PluginStatus::Error("状态转换无效".to_string());
error!("插件 {} 状态转换无效", plugin_id);
failure_count += 1;
}
}
Ok(Err(e)) => {
plugin_instance.status = PluginStatus::Error(e.to_string());
error!("插件启动失败 {}: {}", plugin_id, e);
failure_count += 1;
}
Err(_) => {
plugin_instance.status = PluginStatus::Error("启动超时".to_string());
error!("插件启动超时: {} (超时时间: {}s)", plugin_id, timeout_secs);
failure_count += 1;
}
}
} else {
trace!("插件 {} 状态不是 Initialized,跳过: {:?}", plugin_id, plugin_instance.status);
}
}
}
info!("插件启动完成 - 成功: {}, 失败: {}, 总计: {}",
success_count, failure_count, success_count + failure_count);
trace!("批量启动插件流程完成");
Ok(())
}
pub async fn start_plugin(
plugins: PluginMap,
plugin_id: &str,
timeout_secs: u64,
) -> PluginManagerResult<()> {
trace!("开始启动单个插件: {} (超时: {}s)", plugin_id, timeout_secs);
let sanitized_plugin_id = sanitize_plugin_name(plugin_id)?;
debug!("插件ID清理: {} -> {}", plugin_id, sanitized_plugin_id);
let mut plugins = plugins.write().await;
if let Some(plugin_instance) = plugins.get_mut(&sanitized_plugin_id) {
debug!("找到插件实例: {} (状态: {:?})",
plugin_instance.metadata.name, plugin_instance.status);
if plugin_instance.status == PluginStatus::Initialized {
trace!("插件状态正确,调用 start 方法");
let start_result = timeout(
Duration::from_secs(timeout_secs),
plugin_instance.plugin.start()
).await;
match start_result {
Ok(Ok(_)) => {
if plugin_instance.status.validate_transition(&PluginStatus::Running).is_ok() {
plugin_instance.status = PluginStatus::Running;
info!("插件启动成功: {}", sanitized_plugin_id);
trace!("插件状态已更新为 Running");
} else {
plugin_instance.status = PluginStatus::Error("状态转换无效".to_string());
error!("插件 {} 状态转换无效", sanitized_plugin_id);
return Err(PluginManagerError::StateError("状态转换无效".to_string()));
}
}
Ok(Err(e)) => {
plugin_instance.status = PluginStatus::Error(e.to_string());
error!("插件启动失败 {}: {}", sanitized_plugin_id, e);
return Err(PluginManagerError::ExecutionError(
format!("插件启动失败: {}", e)
));
}
Err(_) => {
plugin_instance.status = PluginStatus::Error("启动超时".to_string());
error!("插件启动超时: {} (超时时间: {}s)", sanitized_plugin_id, timeout_secs);
return Err(PluginManagerError::ExecutionError(
format!("插件启动超时(超时时间: {}秒)", timeout_secs)
));
}
}
} else {
warn!("插件 {} 状态不正确,无法启动: {:?}", sanitized_plugin_id, plugin_instance.status);
return Err(PluginManagerError::StateError(
format!("插件状态不正确,无法启动: {:?}", plugin_instance.status)
));
}
} else {
error!("插件不存在: {}", plugin_id);
return Err(PluginManagerError::not_found(plugin_id));
}
trace!("插件启动流程完成");
Ok(())
}