diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..990d7de --- /dev/null +++ b/src/server.rs @@ -0,0 +1,164 @@ +use crate::db::FutriixDB; +use crate::db; +use crate::lua_interpreter::LuaInterpreter; +use ansi_term::Colour; +use chrono::Local; +use serde::Deserialize; +use std::fs::OpenOptions; +use std::io::Write; +use std::sync::Arc; +use tokio::sync::Mutex; + +#[derive(Debug, Deserialize, Clone)] +pub struct ServerConfig { + pub host: String, + pub port: u16, + pub log_file: String, + pub https_enabled: bool, + pub http2_enabled: bool, + pub ssl_cert: Option, + pub ssl_key: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct DatabaseConfig { + pub data_dir: String, + pub wal_enabled: bool, + pub wal_dir: String, + pub backup_dir: String, + pub replication_enabled: bool, + pub replication_nodes: Vec, + pub sharding_enabled: bool, + pub shards: usize, + pub cluster_mode: bool, + pub gossip_port: u16, + pub gossip_interval_ms: u64, + pub node_id: Option, + pub acl_enabled: bool, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct LuaConfig { + pub scripts_dir: String, + pub auto_load_scripts: bool, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Config { + pub server: ServerConfig, + pub database: DatabaseConfig, + pub lua: LuaConfig, +} + +pub struct FutriixServer { + config: Config, + db: Arc>, + lua_interpreter: LuaInterpreter, +} + +impl FutriixServer { + pub fn new() -> Result> { + // Загрузка конфигурации + let config_str = std::fs::read_to_string("config.toml")?; + let config: Config = toml::from_str(&config_str)?; + + // Создание лог-файла с датой и временем + let mut log_file = OpenOptions::new() + .create(true) + .append(true) + .open(&config.server.log_file)?; + + let now = Local::now(); + writeln!(log_file, "=== Futriix Server Started at {} ===", now.format("%Y-%m-%d %H:%M:%S"))?; + + // Инициализация базы данных + let db_config = db::DatabaseConfig { + data_dir: config.database.data_dir.clone(), + wal_enabled: config.database.wal_enabled, + wal_dir: config.database.wal_dir.clone(), + backup_dir: config.database.backup_dir.clone(), + replication_enabled: config.database.replication_enabled, + replication_nodes: config.database.replication_nodes.clone(), + sharding_enabled: config.database.sharding_enabled, + shards: config.database.shards, + cluster_mode: config.database.cluster_mode, + gossip_port: config.database.gossip_port, + gossip_interval_ms: config.database.gossip_interval_ms, + node_id: config.database.node_id.clone(), + acl_enabled: config.database.acl_enabled, + }; + + let db = FutriixDB::new(&db_config)?; + + // Создаем Arc для базы данных + let db_arc = Arc::new(Mutex::new(db)); + + // Инициализация Lua интерпретатора + let lua_interpreter = LuaInterpreter::new(db_arc.clone(), config.lua.scripts_dir.clone())?; + + Ok(Self { + config, + db: db_arc, + lua_interpreter, + }) + } + + pub async fn run(&mut self) -> Result<(), Box> { + // Запуск HTTP сервера + self.start_http_server()?; + + // Запуск Lua интерпретатора + self.start_lua_interpreter().await?; + + Ok(()) + } + + pub async fn start_gossip(&mut self) -> Result<(), Box> { + let db = self.db.lock().await; + if db.config.cluster_mode { + db.start_gossip().await?; + } else { + println!("{}", Colour::White.paint("Cluster mode disabled in config")); + } + Ok(()) + } + + fn start_http_server(&self) -> Result<(), Box> { + let protocol = if self.config.server.https_enabled { + "HTTPS" + } else { + "HTTP" + }; + + let http2_support = if self.config.server.http2_enabled { + " with HTTP/2" + } else { + "" + }; + + println!("{}", Colour::RGB(0xFF, 0xFF, 0xFF).paint( + format!("{} server starting on port {}{}", protocol, self.config.server.port, http2_support) + )); + + if self.config.server.https_enabled { + println!("{}", Colour::White.paint("SSL/TLS encryption enabled")); + if let Some(cert_path) = &self.config.server.ssl_cert { + println!("{}", Colour::White.paint(format!("SSL certificate: {}", cert_path))); + } + if let Some(key_path) = &self.config.server.ssl_key { + println!("{}", Colour::White.paint(format!("SSL key: {}", key_path))); + } + } + + if self.config.server.http2_enabled { + println!("{}", Colour::White.paint("HTTP/2 protocol enabled")); + } + + Ok(()) + } + + async fn start_lua_interpreter(&mut self) -> Result<(), Box> { + self.lua_interpreter.run().await?; + Ok(()) + } +}