diff --git a/src/plugins/bad-worker.rs b/src/plugins/bad-worker.rs deleted file mode 100644 index 7cf70b5..0000000 --- a/src/plugins/bad-worker.rs +++ /dev/null @@ -1,309 +0,0 @@ -//! Worker поток для обработки сообщений плагинов - -use std::sync::Arc; -use std::thread; -use std::time::Duration; -use parking_lot::RwLock; -use crossbeam::channel::{Sender, TryRecvError}; -use serde_json::Value; - -use crate::plugins::channel::{ - PluginMessage, PluginChannels, HookResponse, LoadPluginResponse, - UnloadPluginResponse, ListPluginsResponse, GetPluginResponse, PluginInfo -}; -use crate::plugins::traits::{PluginEvent, PluginHook, PluginState}; -use crate::plugins::sandbox::LuaSandbox; -use super::Plugin; - -/// Worker для обработки плагинов -pub struct PluginWorker { - channels: PluginChannels, - plugins: Arc>>>, - handle: Option>, - shutdown_flag: Arc>, -} - -impl PluginWorker { - /// Создать новый worker - pub fn new(channels: PluginChannels, plugins: Arc>>>) -> Self { - Self { - channels, - plugins, - handle: None, - shutdown_flag: Arc::new(RwLock::new(false)), - } - } - - /// Запустить worker - pub fn start(&mut self) { - let channels = self.channels.clone(); - let plugins = Arc::clone(&self.plugins); - let shutdown_flag = Arc::clone(&self.shutdown_flag); - - let handle = thread::spawn(move || { - PluginWorker::run_loop(channels, plugins, shutdown_flag); - }); - - self.handle = Some(handle); - } - - /// Основной цикл обработки сообщений - fn run_loop( - channels: PluginChannels, - plugins: Arc>>>, - shutdown_flag: Arc>, - ) { - while !*shutdown_flag.read() { - match channels.try_recv() { - Ok(message) => { - PluginWorker::process_message(message, &channels, &plugins); - } - Err(TryRecvError::Empty) => { - // Нет сообщений, ждем немного - thread::sleep(Duration::from_millis(10)); - } - Err(TryRecvError::Disconnected) => { - // Канал закрыт, выходим - break; - } - } - } - - log::info!("Plugin worker stopped"); - } - - /// Обработать сообщение - fn process_message( - message: PluginMessage, - channels: &PluginChannels, - plugins: &Arc>>>, - ) { - match message { - PluginMessage::Event(event) => { - PluginWorker::handle_event(event, plugins); - } - - PluginMessage::HookRequest { hook_name, data, response_sender } => { - let response = PluginWorker::execute_hook_internal(&hook_name, data, plugins); - let _ = response_sender.send(response); - } - - PluginMessage::LoadPlugin { path, response_sender } => { - let response = PluginWorker::load_plugin_internal(&path, plugins); - let _ = response_sender.send(response); - } - - PluginMessage::UnloadPlugin { plugin_id, response_sender } => { - let response = PluginWorker::unload_plugin_internal(&plugin_id, plugins); - let _ = response_sender.send(response); - } - - PluginMessage::ListPlugins { response_sender } => { - let response = PluginWorker::list_plugins_internal(plugins); - let _ = response_sender.send(response); - } - - PluginMessage::GetPlugin { plugin_id, response_sender } => { - let response = PluginWorker::get_plugin_internal(&plugin_id, plugins); - let _ = response_sender.send(response); - } - - PluginMessage::Shutdown => { - log::info!("Shutdown signal received"); - // Флаг будет установлен в основном цикле - } - } - } - - /// Обработать событие - fn handle_event(event: PluginEvent, plugins: &Arc>>>) { - let plugins_guard = plugins.read(); - - for plugin in plugins_guard.iter() { - if let Some(sandbox) = &plugin.lua_sandbox { - let sandbox_guard = sandbox.read(); - if let Err(e) = sandbox_guard.handle_event(&event) { - log::error!("Failed to handle event in plugin {}: {}", plugin.id, e); - } - } - } - } - - /// Выполнить хук (внутренняя реализация) - fn execute_hook_internal( - hook_name: &str, - data: Value, - plugins: &Arc>>>, - ) -> HookResponse { - let plugins_guard = plugins.read(); - - // Сначала собираем все хуки с указанным именем - let mut hooks = Vec::new(); - - for plugin in plugins_guard.iter() { - for hook in &plugin.hooks { - if hook.name == hook_name { - hooks.push((plugin, hook)); - } - } - } - - // Сортируем по приоритету (высокий приоритет = больше значение) - hooks.sort_by(|a, b| b.1.priority.cmp(&a.1.priority)); - - // Выполняем хуки по порядку - let mut last_result = data; - - for (plugin, hook) in hooks { - if let Some(sandbox) = &plugin.lua_sandbox { - let sandbox_guard = sandbox.read(); - match sandbox_guard.execute_hook(&hook.function, last_result.clone()) { - Ok(result) => { - last_result = result; - } - Err(e) => { - return HookResponse::Error(format!("Failed to execute hook {} in plugin {}: {}", - hook_name, plugin.id, e)); - } - } - } - } - - HookResponse::Success(last_result) - } - - /// Загрузить плагин (внутренняя реализация) - fn load_plugin_internal( - path: &str, - plugins: &Arc>>>, - ) -> LoadPluginResponse { - use std::fs; - - // Проверяем, не загружен ли уже плагин с таким путем - { - let plugins_guard = plugins.read(); - if plugins_guard.iter().any(|p| p.path == path) { - return LoadPluginResponse::Error(format!("Plugin already loaded: {}", path)); - } - } - - // Читаем файл плагина - let content = match fs::read_to_string(path) { - Ok(content) => content, - Err(e) => return LoadPluginResponse::Error(format!("Failed to read plugin file: {}", e)), - }; - - // Создаем песочницу Lua - let sandbox = match LuaSandbox::new() { - Ok(sandbox) => sandbox, - Err(e) => return LoadPluginResponse::Error(format!("Failed to create Lua sandbox: {}", e)), - }; - - // Загружаем плагин в песочницу - let plugin_info = match sandbox.load_plugin(&content, path) { - Ok(info) => info, - Err(e) => return LoadPluginResponse::Error(format!("Failed to load plugin: {}", e)), - }; - - // Создаем объект плагина - let plugin = Arc::new(Plugin { - id: plugin_info.id.clone(), - name: plugin_info.name.clone(), - version: plugin_info.version.clone(), - description: plugin_info.description.clone(), - author: plugin_info.author.clone(), - path: path.to_string(), - state: PluginState::Loaded, - hooks: plugin_info.hooks.clone(), - lua_sandbox: Some(Arc::new(RwLock::new(sandbox))), - }); - - // Добавляем плагин в список - { - let mut plugins_guard = plugins.write(); - plugins_guard.push(plugin); - } - - log::info!("Plugin loaded: {} v{}", plugin_info.name, plugin_info.version); - LoadPluginResponse::Success(plugin_info.id) - } - - /// Выгрузить плагин (внутренняя реализация) - fn unload_plugin_internal( - plugin_id: &str, - plugins: &Arc>>>, - ) -> UnloadPluginResponse { - let mut plugins_guard = plugins.write(); - - if let Some(pos) = plugins_guard.iter().position(|p| p.id == plugin_id) { - let plugin = plugins_guard.remove(pos); - log::info!("Plugin unloaded: {} v{}", plugin.name, plugin.version); - UnloadPluginResponse::Success - } else { - UnloadPluginResponse::Error(format!("Plugin not found: {}", plugin_id)) - } - } - - /// Получить список плагинов (внутренняя реализация) - fn list_plugins_internal( - plugins: &Arc>>>, - ) -> ListPluginsResponse { - let plugins_guard = plugins.read(); - - let plugin_infos = plugins_guard.iter().map(|plugin| { - PluginInfo { - id: plugin.id.clone(), - name: plugin.name.clone(), - version: plugin.version.clone(), - description: plugin.description.clone(), - author: plugin.author.clone(), - path: plugin.path.clone(), - state: format!("{:?}", plugin.state), - hooks: plugin.hooks.clone(), - } - }).collect(); - - ListPluginsResponse { - plugins: plugin_infos, - } - } - - /// Получить информацию о плагине (внутренняя реализация) - fn get_plugin_internal( - plugin_id: &str, - plugins: &Arc>>>, - ) -> GetPluginResponse { - let plugins_guard = plugins.read(); - - if let Some(plugin) = plugins_guard.iter().find(|p| p.id == plugin_id) { - let info = PluginInfo { - id: plugin.id.clone(), - name: plugin.name.clone(), - version: plugin.version.clone(), - description: plugin.description.clone(), - author: plugin.author.clone(), - path: plugin.path.clone(), - state: format!("{:?}", plugin.state), - hooks: plugin.hooks.clone(), - }; - GetPluginResponse::Found(info) - } else { - GetPluginResponse::NotFound - } - } - - /// Остановить worker - pub fn shutdown(&self) { - *self.shutdown_flag.write() = true; - - if let Some(handle) = self.handle.take() { - let _ = handle.join(); - } - } -} - -impl Drop for PluginWorker { - fn drop(&mut self) { - self.shutdown(); - } -}