Skip to main content

flare_core_runtime/plugin/
manager.rs

1//! 插件管理器实现
2//!
3//! 管理所有插件并在关键生命周期调用插件钩子
4
5use super::{Plugin, PluginContext};
6use crate::error::PluginError;
7use std::sync::Arc;
8use tracing::{error, warn};
9
10/// 插件管理器
11///
12/// 管理所有插件并在关键生命周期调用插件钩子
13///
14/// # 示例
15///
16/// ```rust,ignore
17/// use flare_core_runtime::plugin::{PluginManager, Plugin};
18///
19/// let mut manager = PluginManager::new();
20/// manager.register(Box::new(MyPlugin));
21///
22/// // 调用生命周期钩子
23/// manager.on_startup(&ctx).await?;
24/// ```
25pub struct PluginManager {
26    plugins: Vec<Arc<dyn Plugin>>,
27}
28
29impl PluginManager {
30    /// 创建新的插件管理器
31    pub fn new() -> Self {
32        Self {
33            plugins: Vec::new(),
34        }
35    }
36
37    /// 注册插件
38    ///
39    /// # 参数
40    ///
41    /// * `plugin` - 要注册的插件
42    pub fn register(&mut self, plugin: Arc<dyn Plugin>) {
43        let name = plugin.name().to_string();
44        self.plugins.push(plugin);
45        tracing::debug!(plugin_name = %name, "Plugin registered");
46    }
47
48    /// 运行时启动时调用
49    ///
50    /// 调用所有插件的 `on_startup` 钩子
51    pub async fn on_startup(&self, ctx: &PluginContext) -> Result<(), PluginError> {
52        for plugin in &self.plugins {
53            if let Err(e) = plugin.on_startup(ctx).await {
54                error!(
55                    plugin_name = %plugin.name(),
56                    error = %e,
57                    "Plugin on_startup failed"
58                );
59                // 插件失败不影响运行时,继续执行其他插件
60            }
61        }
62        Ok(())
63    }
64
65    /// 任务启动前调用
66    ///
67    /// 调用所有插件的 `on_task_start` 钩子
68    pub async fn on_task_start(&self, ctx: &PluginContext) -> Result<(), PluginError> {
69        for plugin in &self.plugins {
70            if let Err(e) = plugin.on_task_start(ctx).await {
71                warn!(
72                    plugin_name = %plugin.name(),
73                    error = %e,
74                    "Plugin on_task_start failed"
75                );
76            }
77        }
78        Ok(())
79    }
80
81    /// 任务停止后调用
82    ///
83    /// 调用所有插件的 `on_task_stop` 钩子
84    pub async fn on_task_stop(&self, ctx: &PluginContext) -> Result<(), PluginError> {
85        for plugin in &self.plugins {
86            if let Err(e) = plugin.on_task_stop(ctx).await {
87                warn!(
88                    plugin_name = %plugin.name(),
89                    error = %e,
90                    "Plugin on_task_stop failed"
91                );
92            }
93        }
94        Ok(())
95    }
96
97    /// 运行时停机时调用
98    ///
99    /// 调用所有插件的 `on_shutdown` 钩子
100    pub async fn on_shutdown(&self, ctx: &PluginContext) -> Result<(), PluginError> {
101        for plugin in &self.plugins {
102            if let Err(e) = plugin.on_shutdown(ctx).await {
103                warn!(
104                    plugin_name = %plugin.name(),
105                    error = %e,
106                    "Plugin on_shutdown failed"
107                );
108            }
109        }
110        Ok(())
111    }
112
113    /// 错误发生时调用
114    ///
115    /// 调用所有插件的 `on_error` 钩子
116    pub async fn on_error(&self, ctx: &PluginContext, error: &str) -> Result<(), PluginError> {
117        for plugin in &self.plugins {
118            if let Err(e) = plugin.on_error(ctx, error).await {
119                warn!(
120                    plugin_name = %plugin.name(),
121                    error = %e,
122                    "Plugin on_error failed"
123                );
124            }
125        }
126        Ok(())
127    }
128
129    /// 获取插件数量
130    pub fn plugin_count(&self) -> usize {
131        self.plugins.len()
132    }
133}
134
135impl Default for PluginManager {
136    fn default() -> Self {
137        Self::new()
138    }
139}
140
141#[cfg(test)]
142mod tests {
143    use super::*;
144    use crate::task::TaskState;
145
146    struct TestPlugin {
147        name: String,
148    }
149
150    impl Plugin for TestPlugin {
151        fn name(&self) -> &str {
152            &self.name
153        }
154    }
155
156    #[tokio::test]
157    async fn test_plugin_manager_register() {
158        let mut manager = PluginManager::new();
159        manager.register(Arc::new(TestPlugin {
160            name: "test-plugin".to_string(),
161        }));
162
163        assert_eq!(manager.plugin_count(), 1);
164    }
165
166    #[tokio::test]
167    async fn test_plugin_manager_on_startup() {
168        let mut manager = PluginManager::new();
169        manager.register(Arc::new(TestPlugin {
170            name: "test-plugin".to_string(),
171        }));
172
173        let ctx = PluginContext::new("test-runtime");
174        let result = manager.on_startup(&ctx).await;
175        assert!(result.is_ok());
176    }
177}