mf_state/plugin/
manager.rs1use std::collections::{HashMap, HashSet};
2use std::sync::atomic::{AtomicBool, Ordering};
3use std::sync::Arc;
4use anyhow::Result;
5
6use super::dependency::DependencyManager;
7use super::plugin::Plugin;
8
9#[derive(Debug, Clone)]
42pub struct PluginManager {
43 plugins: Arc<HashMap<String, Arc<Plugin>>>,
45 sorted_plugins: Arc<Vec<Arc<Plugin>>>,
47 initialized: Arc<AtomicBool>,
49}
50
51pub struct PluginManagerBuilder {
55 plugins: HashMap<String, Arc<Plugin>>,
56 dependency_manager: DependencyManager,
57}
58
59impl PluginManagerBuilder {
60 pub fn new() -> Self {
62 Self {
63 plugins: HashMap::new(),
64 dependency_manager: DependencyManager::new(),
65 }
66 }
67
68 #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, plugin), fields(
75 crate_name = "state",
76 plugin_name = %plugin.spec.tr.metadata().name
77 )))]
78 pub fn register_plugin(
79 &mut self,
80 plugin: Arc<Plugin>,
81 ) -> Result<()> {
82 let plugin_name = plugin.spec.tr.metadata().name.clone();
83
84 if self.plugins.contains_key(&plugin_name) {
86 return Err(anyhow::anyhow!("插件 '{}' 已存在", plugin_name));
87 }
88
89 let metadata = plugin.spec.tr.metadata();
91 self.dependency_manager.add_plugin(&metadata.name);
92 for dep in &metadata.dependencies {
93 self.dependency_manager.add_dependency(&metadata.name, dep)?;
94 }
95
96 self.plugins.insert(plugin_name.clone(), plugin);
98
99 tracing::debug!("插件 '{}' 注册成功", plugin_name);
100 Ok(())
101 }
102
103 #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self), fields(
121 crate_name = "state",
122 plugin_count = self.plugins.len()
123 )))]
124 pub fn build(self) -> Result<PluginManager> {
125 if self.dependency_manager.has_circular_dependencies() {
127 let report =
128 self.dependency_manager.get_circular_dependency_report();
129 return Err(anyhow::anyhow!(
130 "检测到循环依赖: {}",
131 report.to_string()
132 ));
133 }
134
135 let missing_report =
137 self.dependency_manager.check_missing_dependencies();
138 if missing_report.has_missing_dependencies {
139 return Err(anyhow::anyhow!(
140 "检测到缺失依赖: {}",
141 missing_report.to_string()
142 ));
143 }
144
145 let available_plugins: HashSet<String> =
147 self.plugins.keys().cloned().collect();
148 for (name, plugin) in &self.plugins {
149 let metadata = plugin.spec.tr.metadata();
150 for conflict in &metadata.conflicts {
151 if available_plugins.contains(conflict) {
152 return Err(anyhow::anyhow!(
153 "插件 '{}' 与插件 '{}' 冲突",
154 name,
155 conflict
156 ));
157 }
158 }
159 }
160
161 let plugin_order = self.dependency_manager.get_topological_order()?;
163
164 let sorted_plugins: Vec<Arc<Plugin>> = plugin_order
166 .iter()
167 .filter_map(|name| self.plugins.get(name).cloned())
168 .collect();
169
170 tracing::info!(
171 "插件管理器构建完成,共注册 {} 个插件",
172 self.plugins.len()
173 );
174
175 Ok(PluginManager {
176 plugins: Arc::new(self.plugins),
177 sorted_plugins: Arc::new(sorted_plugins),
178 initialized: Arc::new(AtomicBool::new(true)),
179 })
180 }
181}
182
183impl Default for PluginManagerBuilder {
184 fn default() -> Self {
185 Self::new()
186 }
187}
188
189impl PluginManager {
190 pub fn new() -> Self {
192 Self {
193 plugins: Arc::new(HashMap::new()),
194 sorted_plugins: Arc::new(Vec::new()),
195 initialized: Arc::new(AtomicBool::new(true)),
196 }
197 }
198
199 #[inline]
211 pub async fn get_sorted_plugins(&self) -> Vec<Arc<Plugin>> {
212 self.sorted_plugins.as_ref().clone()
214 }
215
216 #[inline]
228 pub fn get_sorted_plugins_sync(&self) -> &[Arc<Plugin>] {
229 self.sorted_plugins.as_ref()
230 }
231
232 #[inline]
236 pub async fn is_initialized(&self) -> bool {
237 self.initialized.load(Ordering::Acquire)
238 }
239
240 #[inline]
242 pub fn is_initialized_sync(&self) -> bool {
243 self.initialized.load(Ordering::Acquire)
244 }
245
246 #[inline]
248 pub fn plugin_count(&self) -> usize {
249 self.plugins.len()
250 }
251
252 #[inline]
258 pub fn get_plugin(
259 &self,
260 name: &str,
261 ) -> Option<&Arc<Plugin>> {
262 self.plugins.get(name)
263 }
264
265 #[inline]
267 pub fn has_plugin(
268 &self,
269 name: &str,
270 ) -> bool {
271 self.plugins.contains_key(name)
272 }
273}
274
275impl Default for PluginManager {
276 fn default() -> Self {
277 Self::new()
278 }
279}