// src/server/mod.rs //! Сервер Falcot - документо-ориентированная БД с wait-free архитектурой //! //! Основной модуль сервера, реализующий wait-free доступ к данным, //! синхронную master-master репликацию и поддержку HTTP/HTTPS. #![allow(dead_code)] use std::sync::Arc; use std::fs::OpenOptions; use std::io::Write; use crate::common::error::Result; use crate::lua_shell::LuaShell; // Импортируем подмодули pub mod database; pub mod replication; pub mod lua_engine; pub mod messagepack; pub mod config; pub mod http; pub mod sharding; // Добавляем модуль шардинга /// Функция для логирования в файл fn log_to_file(message: &str) { if let Ok(mut file) = OpenOptions::new() .create(true) .append(true) .open("falcot.log") { let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S"); let log_message = format!("[{}] {}\n", timestamp, message); let _ = file.write_all(log_message.as_bytes()); } } /// Функция для вывода текста с ANSI цветом #[allow(dead_code)] fn print_colored(text: &str, ansi_color: &str) { println!("{}{}\x1b[0m", ansi_color, text); } /// Конвертация HEX цвета в ANSI escape code 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() } /// Основный сервер Falcot с wait-free архитектурой pub struct FalcotServer { config: config::Config, database: Arc, lua_engine: lua_engine::LuaEngine, replication: Arc, http_enabled: bool, } impl FalcotServer { /// Создание нового сервера с wait-free архитектурой pub async fn new(config_path: &str) -> Result { // Загрузка конфигурации let config = config::Config::load(config_path)?; // Инициализация компонентов с wait-free подходами let database = Arc::new(database::Database::new()); let lua_engine = lua_engine::LuaEngine::new()?; let replication = Arc::new(replication::ReplicationManager::new( config.replication.master_nodes.iter() .map(|addr| addr.to_string()) .collect(), config.replication.sync_interval, config.replication.enabled, )); // Регистрация функций БД в Lua lua_engine.register_db_functions(database.clone())?; // Инициализация базы данных FalcotServer::initialize_database(database.clone())?; // Проверяем, включен ли HTTP режим let http_enabled = config.server.http_port.is_some() || config.server.https_port.is_some(); Ok(Self { config, database, lua_engine, replication, http_enabled, }) } /// Инициализация базы данных с wait-free структурами fn initialize_database(db: Arc) -> Result<()> { // Создаем системные коллекции с wait-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 backup_dir = "/falcot/backups"; if let Err(e) = std::fs::create_dir_all(backup_dir) { eprintln!("Warning: Failed to create backup directory: {}", e); } let message = "Database initialized with system collections"; println!("{}", message); log_to_file(message); Ok(()) } /// Запуск сервера с wait-free архитектурой pub async fn run(&self) -> Result<()> { // Вывод приветственного сообщения с цветом #00bfff println!(); let color_code = hex_to_ansi("#00bfff"); print_colored("Falcot Database Server", &color_code); println!(); println!("Version: 1.0.0"); println!("Features: Wait-Free Architecture, Master-Master Replication, Lua Scripting, HTTP/HTTPS Support"); log_to_file("Falcot Database Server started"); log_to_file("Version: 1.0.0"); // Запуск HTTP/HTTPS серверов в отдельных задачах, если настроены if self.http_enabled { self.start_http_servers().await?; } // Запуск Lua интерпретатора println!("Starting Lua interpreter..."); log_to_file("Starting Lua interpreter..."); let mut lua_shell = LuaShell::new( self.lua_engine.clone(), self.database.clone(), self.replication.clone() ); // Запуск интерактивной оболочки lua_shell.run().await?; Ok(()) } /// Запуск HTTP/HTTPS серверов в отдельных задачах async fn start_http_servers(&self) -> Result<()> { let static_config = http::StaticFilesConfig::default(); let acl_config = http::AclConfig { enabled: self.config.acl.enabled, allowed_ips: self.config.acl.allowed_ips.clone(), denied_ips: self.config.acl.denied_ips.clone(), }; // Запуск HTTP сервера, если настроен if let Some(http_port) = self.config.server.http_port { let http_addr = format!("{}:{}", self.config.server.host, http_port); let http_config = 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(); // Запускаем HTTP сервер в отдельной задаче (не блокирующей основной поток) tokio::spawn(async move { match 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); } } }); } // Запуск HTTPS сервера, если настроен if let Some(https_port) = self.config.server.https_port { let https_addr = format!("{}:{}", self.config.server.host, https_port); let tls_config = 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(); // Запускаем HTTPS сервер в отдельной задаче tokio::spawn(async move { match 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); } } }); } Ok(()) } }