From eed8b66810107df5141213af724b07e5e1ee0971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=B0=D1=84=D1=80=D0=BE=D0=BD=D0=BE=D0=B2?= Date: Sat, 6 Dec 2025 19:30:23 +0000 Subject: [PATCH] Upload files to "src/server" --- src/server/mod.rs | 824 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 824 insertions(+) create mode 100644 src/server/mod.rs diff --git a/src/server/mod.rs b/src/server/mod.rs new file mode 100644 index 0000000..2ce63ed --- /dev/null +++ b/src/server/mod.rs @@ -0,0 +1,824 @@ +// src/server/mod.rs +//! Сервер Futriix - полностью lock-free документо-ориентированная БД +//! +//! Основной модуль сервера, который инициализирует все компоненты системы: +//! - Базу данных с lock-free архитектурой +//! - Lua движок для выполнения скриптов +//! - Менеджер шардинга и репликации +//! - HTTP/HTTPS серверы +//! - CSV менеджер для импорта/экспорта данных +//! +//! Архитектурные особенности: +//! - Все операции выполняются без блокировок (lock-free) +//! - Используются атомарные структуры данных +//! - Поддержка транзакций через Software Transactional Memory +//! - Интеграция с Lua для кастомной логики + +#![allow(dead_code)] + +use std::sync::Arc; +use std::fs::OpenOptions; +use std::io::Write; + +use crate::common::Result; +use crate::common::config::Config; +use crate::lua_shell::LuaShell; + +// Импортируем подмодули +pub mod database; +pub mod lua_engine; +pub mod http; +pub mod sharding; +pub mod csv_import_export; + +/// Функция для логирования в файл +/// Используется для отладки и аудита работы сервера +/// Все сообщения записываются в файл futriix.log с временными метками +fn log_to_file(message: &str) { + if let Ok(mut file) = OpenOptions::new() + .create(true) + .append(true) + .open("futriix.log") + { + let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f").to_string(); + let log_message = format!("[{}] {}\n", timestamp, message); + let _ = file.write_all(log_message.as_bytes()); + } +} + +/// Функция для вывода текста с ANSI цветом +/// Использует escape-последовательности для цветного форматирования вывода +#[allow(dead_code)] +fn print_colored(text: &str, ansi_color: &str) { + println!("{}{}\x1b[0m", ansi_color, text); +} + +/// Конвертация HEX цвета в ANSI escape code +/// Поддерживает формат #RRGGBB для установки произвольных цветов +fn hex_to_ansi(hex_color: &str) -> String { + let hex = hex_color.trim_start_matches('#'); + + if hex.len() == 6 { + if let (Ok(r), Ok(g), Ok(b)) = ( + u8::from_str_radix(&hex[0..2], 16), + u8::from_str_radix(&hex[2..4], 16), + u8::from_str_radix(&hex[4..6], 16), + ) { + return format!("\x1b[38;2;{};{};{}m", r, g, b); + } + } + + // Цвет по умолчанию: белый + "\x1b[38;2;255;255;255m".to_string() +} + +/// Основный сервер Futriix с полностью lock-free архитектурой +/// Координирует работу всех компонентов системы и предоставляет +/// единую точку входа для управления базой данных +pub struct FutriixServer { + config: Config, // Конфигурация сервера + database: Arc, // Lock-free база данных + lua_engine: lua_engine::LuaEngine, // Встроенный Lua интерпретатор + sharding_manager: Arc, // Менеджер шардинга и репликации + http_enabled: bool, // Флаг включения HTTP сервера + csv_manager: Arc, // Менеджер CSV операций +} + +impl FutriixServer { + /// Создание нового сервера с lock-free архитектурой + /// Инициализирует все компоненты системы на основе конфигурации + pub async fn new(config_path: &str) -> Result { + // Загрузка конфигурации из файла TOML + let config = Config::load(config_path)?; + + // Инициализация компонентов с lock-free подходами + let database = Arc::new(database::Database::new()); + let lua_engine = lua_engine::LuaEngine::new()?; + + // Генерируем уникальный ID для текущего узла + let node_id = format!("node_{}", uuid::Uuid::new_v4().to_string()[..8].to_string()); + + // Инициализация менеджера шардинга и репликации + let sharding_manager = Arc::new(sharding::ShardingManager::new( + config.sharding.virtual_nodes_per_node, + config.replication.enabled, + config.sharding.min_nodes_for_cluster, + node_id, + )); + + // Инициализация менеджера CSV + let csv_manager = Arc::new(csv_import_export::CsvManager::new( + database.clone(), + config.csv.clone(), + )); + + // Регистрация функций БД в Lua движке + // Это позволяет выполнять Lua скрипты с доступом к базе данных + lua_engine.register_db_functions(database.clone(), sharding_manager.clone())?; + + // Инициализация базы данных (создание системных коллекций и директорий) + FutriixServer::initialize_database(database.clone())?; + + // Проверяем, включен ли HTTP режим в конфигурации + let http_enabled = (config.server.http_port.is_some() && config.server.http) || + (config.server.https_port.is_some() && config.server.https); + + Ok(Self { + config, + database, + lua_engine, + sharding_manager, + http_enabled, + csv_manager, + }) + } + + /// Инициализация базы данных с lock-free структурами + /// Создает системные коллекции, директории для бэкапов и статических файлов + fn initialize_database(db: Arc) -> Result<()> { + // Создаем системные коллекции с lock-free доступом + // Эти коллекции используются для внутренних нужд системы + let _system_collection = db.get_collection("_system"); + let _users_collection = db.get_collection("_users"); + let _logs_collection = db.get_collection("_logs"); + let _procedures_collection = db.get_collection("_procedures"); + let _triggers_collection = db.get_collection("_triggers"); + let _csv_imports_collection = db.get_collection("_csv_imports"); + + // Создаем директорию для бэкапов, если она не существует + let backup_dir = "./futriix_backups"; + if let Err(e) = std::fs::create_dir_all(backup_dir) { + eprintln!("Warning: Failed to create backup directory '{}': {}", backup_dir, e); + } else { + println!("Backup directory created at: {}", backup_dir); + } + + // Создаем директорию для CSV файлов + let csv_dir = "./futriix_csv"; + if let Err(e) = std::fs::create_dir_all(csv_dir) { + eprintln!("Warning: Failed to create CSV directory '{}': {}", csv_dir, e); + } else { + println!("CSV directory created at: {}", csv_dir); + } + + // Создаем поддиректории для CSV импорта и экспорта + let import_dir = "./futriix_csv/import"; + let export_dir = "./futriix_csv/export"; + let _ = std::fs::create_dir_all(import_dir); + let _ = std::fs::create_dir_all(export_dir); + + // Создаем директорию для статических файлов веб-интерфейса + let static_dir = "static"; + if let Err(e) = std::fs::create_dir_all(static_dir) { + eprintln!("Warning: Failed to create static files directory '{}': {}", static_dir, e); + } else { + println!("Static files directory created at: {}", static_dir); + } + + // ИЗМЕНЕНИЕ: Создаем простой default.html для тестирования вместо index.html + // Используем default.html как точку входа для веб-интерфейса Futriix + let default_html_content = r#" + + + Futriix Database Server + + + + + +
+
+ +
v1.0.0 • futriix 3i²
+
+ +
+
+
🚀
+
Server Status
+
Online
+
Ready to accept connections
+
+ +
+
🗄️
+
Database
+
Active
+
Lock-free architecture
+
+ +
+
⚙️
+
Lua Engine
+
Running
+
Script execution enabled
+
+ +
+
🔗
+
Cluster Mode
+
Checking...
+
Sharding & Replication
+
+
+ +
+
System Information
+
+
+
Server Version
+
Futriix 1.0.0
+
+
+
Architecture
+
Wait-Free / Lock-Free
+
+
+
Protocol Support
+
HTTP/1.1, HTTP/2, HTTPS
+
+
+
Default Ports
+
HTTP: 9090, HTTPS: 8443
+
+
+ +
+
+
📊
+
Real-time Analytics
+
+
+
🔒
+
Atomic Transactions
+
+
+
🚀
+
High Performance
+
+
+
📝
+
Lua Scripting
+
+
+
🔄
+
Auto-Sharding
+
+
+
💾
+
CSV Import/Export
+
+
+
+ + + +
+
Server Time
+
Loading...
+
+ +
+

© 2025 Futriix Database Server. All rights reserved.

+

Built with Rust • Lock-Free Architecture • Enterprise Ready

+
+
+ + + +"#; + + // ИЗМЕНЕНИЕ: Сохраняем как default.html вместо index.html + // Это обеспечивает лучшую совместимость и избегает конфликтов с другими системами + if let Err(e) = std::fs::write("static/default.html", default_html_content) { + eprintln!("Warning: Failed to create default.html: {}", e); + } else { + println!("Created enhanced default.html in static directory"); + println!("Web interface will be available at: http://localhost:9090/default.html"); + } + + let message = "Database initialized with system collections"; + println!("{}", message); + log_to_file(message); + + Ok(()) + } + + /// Запуск сервера с lock-free архитектурой + /// Координирует запуск HTTP серверов и интерактивной оболочки + pub async fn run(&self) -> Result<()> { + // Определяем режим работы и имя кластера + let cluster_name = &self.config.cluster.name; + + println!("Run: cluster (cluster: '{}')", cluster_name); + + log_to_file("Futriix Database Server started"); + log_to_file(&format!("Run: cluster (cluster: '{}')", cluster_name)); + + // Сначала запускаем HTTP серверы и ждем их запуска + if self.http_enabled { + self.start_http_servers().await?; + } else { + println!("HTTP/HTTPS servers disabled in configuration"); + } + + // Добавляем пустую строку после информации о серверах + println!(); + + let mut lua_shell = LuaShell::new( + self.lua_engine.clone(), + self.database.clone(), + self.sharding_manager.clone(), + self.csv_manager.clone(), + ); + + // Запуск интерактивной оболочки + lua_shell.run().await?; + + Ok(()) + } + + /// Запуск HTTP/HTTPS серверов с ожиданием их готовности + /// Создает отдельные задачи для каждого сервера и управляет их жизненным циклом + async fn start_http_servers(&self) -> Result<()> { + let static_config = self::http::StaticFilesConfig::default(); + let acl_config = self::http::AclConfig { + enabled: self.config.acl.enabled, + allowed_ips: self.config.acl.allowed_ips.clone(), + denied_ips: self.config.acl.denied_ips.clone(), + }; + + let mut http_server_handles = Vec::new(); + + // Запуск HTTP сервера, если настроен и включен + if let Some(http_port) = self.config.server.http_port { + if self.config.server.http { + let http_addr = format!("{}:{}", self.config.server.host, http_port); + let http_config = self::http::HttpConfig { + enabled: true, + port: http_port, + http2_enabled: self.config.server.http2_enabled.unwrap_or(false), + }; + + let db_clone = self.database.clone(); + let static_config_clone = static_config.clone(); + let acl_config_clone = acl_config.clone(); + + println!("Starting HTTP server on {}", http_addr); + + // Запускаем в фоновой задаче + let handle = tokio::spawn(async move { + match self::http::start_http_server(&http_addr, db_clone, static_config_clone, http_config, acl_config_clone).await { + Ok(_) => { + let message = format!("HTTP server started on {}", http_addr); + println!("{}", message); + log_to_file(&message); + } + Err(e) => { + let message = format!("Failed to start HTTP server: {}", e); + eprintln!("{}", message); + log_to_file(&message); + } + } + }); + + http_server_handles.push(handle); + } else { + println!("HTTP server disabled in configuration"); + } + } + + // Запуск HTTPS сервера, если настроен и включен + if let Some(https_port) = self.config.server.https_port { + if self.config.server.https && self.config.tls.enabled { + let https_addr = format!("{}:{}", self.config.server.host, https_port); + let tls_config = self::http::TlsConfig { + enabled: self.config.tls.enabled, + cert_path: self.config.tls.cert_path.clone(), + key_path: self.config.tls.key_path.clone(), + }; + + let db_clone = self.database.clone(); + let static_config_clone = static_config.clone(); + let acl_config_clone = acl_config.clone(); + + println!("Starting HTTPS server on {}", https_addr); + + let handle = tokio::spawn(async move { + match self::http::start_https_server(&https_addr, db_clone, static_config_clone, tls_config, acl_config_clone).await { + Ok(_) => { + let message = format!("HTTPS server started on {}", https_addr); + println!("{}", message); + log_to_file(&message); + } + Err(e) => { + let message = format!("Failed to start HTTPS server: {}", e); + eprintln!("{}", message); + log_to_file(&message); + } + } + }); + + http_server_handles.push(handle); + } else { + if !self.config.tls.enabled { + println!("HTTPS disabled: TLS not enabled in configuration"); + } else { + println!("HTTPS server disabled in configuration"); + } + } + } + + // Ждем небольшое время, чтобы серверы успели стартовать + if !http_server_handles.is_empty() { + println!("Waiting for HTTP servers to start..."); + tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; + } + + Ok(()) + } + + /// Получение менеджера шардинга для внешнего использования + #[allow(dead_code)] + pub fn get_sharding_manager(&self) -> Arc { + self.sharding_manager.clone() + } + + /// Получение менеджера CSV для внешнего использования + #[allow(dead_code)] + pub fn get_csv_manager(&self) -> Arc { + self.csv_manager.clone() + } + + /// Получение базы данных для внешнего использования + #[allow(dead_code)] + pub fn get_database(&self) -> Arc { + self.database.clone() + } + + /// Получение Lua движка для внешнего использования + #[allow(dead_code)] + pub fn get_lua_engine(&self) -> lua_engine::LuaEngine { + self.lua_engine.clone() + } +}