Delete src/plugins/bad-worker.rs

This commit is contained in:
Григорий Сафронов 2026-01-18 21:55:20 +00:00
parent 709e35f929
commit 8ecb76101b

View File

@ -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<RwLock<Vec<Arc<Plugin>>>>,
handle: Option<thread::JoinHandle<()>>,
shutdown_flag: Arc<RwLock<bool>>,
}
impl PluginWorker {
/// Создать новый worker
pub fn new(channels: PluginChannels, plugins: Arc<RwLock<Vec<Arc<Plugin>>>>) -> 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<RwLock<Vec<Arc<Plugin>>>>,
shutdown_flag: Arc<RwLock<bool>>,
) {
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<RwLock<Vec<Arc<Plugin>>>>,
) {
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<RwLock<Vec<Arc<Plugin>>>>) {
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<RwLock<Vec<Arc<Plugin>>>>,
) -> 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<RwLock<Vec<Arc<Plugin>>>>,
) -> 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<RwLock<Vec<Arc<Plugin>>>>,
) -> 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<RwLock<Vec<Arc<Plugin>>>>,
) -> 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<RwLock<Vec<Arc<Plugin>>>>,
) -> 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();
}
}