Delete src/server/mod.rs
This commit is contained in:
parent
3432d699ec
commit
71c3989cc2
@ -1,331 +0,0 @@
|
|||||||
// src/server/mod.rs
|
|
||||||
//! Сервер Futriix - документо-ориентированная БД с 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::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; // Модуль для CSV импорта/экспорта
|
|
||||||
|
|
||||||
/// Функция для логирования в файл
|
|
||||||
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 цветом
|
|
||||||
#[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()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Основный сервер Futriix с wait-free архитектураой
|
|
||||||
pub struct FutriixServer {
|
|
||||||
config: Config,
|
|
||||||
database: Arc<database::Database>,
|
|
||||||
lua_engine: lua_engine::LuaEngine,
|
|
||||||
sharding_manager: Arc<sharding::ShardingManager>, // Объединенный менеджер
|
|
||||||
http_enabled: bool,
|
|
||||||
csv_manager: Arc<csv_import_export::CsvManager>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FutriixServer {
|
|
||||||
/// Создание нового сервера с wait-free архитектурой
|
|
||||||
pub async fn new(config_path: &str) -> Result<Self> {
|
|
||||||
// Загрузка конфигурации
|
|
||||||
let config = Config::load(config_path)?;
|
|
||||||
|
|
||||||
// Инициализация компонентов с wait-free подходами
|
|
||||||
let database = Arc::new(database::Database::new());
|
|
||||||
let lua_engine = lua_engine::LuaEngine::new()?;
|
|
||||||
|
|
||||||
// Инициализация объединенного менеджера шардинга и репликации
|
|
||||||
let sharding_manager = Arc::new(sharding::ShardingManager::new(
|
|
||||||
160, // virtual_nodes_per_node
|
|
||||||
config.replication.enabled,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Инициализация менеджера CSV
|
|
||||||
let csv_manager = Arc::new(csv_import_export::CsvManager::new(
|
|
||||||
database.clone(),
|
|
||||||
config.csv.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Регистрация функций БД в 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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Инициализация базы данных с wait-free структурами
|
|
||||||
fn initialize_database(db: Arc<database::Database>) -> 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 _csv_imports_collection = db.get_collection("_csv_imports");
|
|
||||||
|
|
||||||
// Создаем директорию для бэкапов
|
|
||||||
let backup_dir = "/futriix/backups";
|
|
||||||
if let Err(e) = std::fs::create_dir_all(backup_dir) {
|
|
||||||
// Используем текущую директорию как запасной вариант
|
|
||||||
let current_backup_dir = "./futriix_backups";
|
|
||||||
if let Err(e2) = std::fs::create_dir_all(current_backup_dir) {
|
|
||||||
eprintln!("Warning: Failed to create backup directory '{}': {}", backup_dir, e);
|
|
||||||
eprintln!("Warning: Also failed to create fallback directory '{}': {}", current_backup_dir, e2);
|
|
||||||
} else {
|
|
||||||
println!("Backup directory created at: {}", current_backup_dir);
|
|
||||||
}
|
|
||||||
} 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) {
|
|
||||||
// Используем текущую директорию как запасной вариант
|
|
||||||
let current_csv_dir = "./futriix_csv";
|
|
||||||
if let Err(e2) = std::fs::create_dir_all(current_csv_dir) {
|
|
||||||
eprintln!("Warning: Failed to create CSV directory '{}': {}", csv_dir, e);
|
|
||||||
eprintln!("Warning: Also failed to create fallback directory '{}': {}", current_csv_dir, e2);
|
|
||||||
} else {
|
|
||||||
println!("CSV directory created at: {}", current_csv_dir);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println!("CSV directory created at: {}", csv_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// СОЗДАЕМ ПРОСТОЙ INDEX.HTML ДЛЯ ТЕСТИРОВАНИЯ
|
|
||||||
let index_html_content = r#"<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Futriix Database Server</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: Arial, sans-serif; margin: 40px; }
|
|
||||||
h1 { color: #00bfff; }
|
|
||||||
.status { padding: 10px; background: #f0f0f0; border-radius: 5px; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Futriix Database Server</h1>
|
|
||||||
<div class="status">
|
|
||||||
<p>Server is running successfully!</p>
|
|
||||||
<p>This is a test page to verify HTTP server functionality.</p>
|
|
||||||
<p>Current time: <span id="time"></span></p>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
document.getElementById('time').textContent = new Date().toLocaleString();
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>"#;
|
|
||||||
|
|
||||||
if let Err(e) = std::fs::write("static/index.html", index_html_content) {
|
|
||||||
eprintln!("Warning: Failed to create index.html: {}", e);
|
|
||||||
} else {
|
|
||||||
println!("Created test index.html in static directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
let message = "Database initialized with system collections";
|
|
||||||
println!("{}", message);
|
|
||||||
log_to_file(message);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Запуск сервера с wait-free архитектурой
|
|
||||||
pub async fn run(&self) -> Result<()> {
|
|
||||||
// Определяем режим работы и имя кластера
|
|
||||||
let cluster_name = &self.config.cluster.name;
|
|
||||||
|
|
||||||
// ИЗМЕНЕНИЕ: Заменено "Mode" на "Run"
|
|
||||||
println!("Run: cluster (cluster: '{}')", cluster_name);
|
|
||||||
|
|
||||||
log_to_file("Futriix Database Server started");
|
|
||||||
log_to_file(&format!("Run: cluster (cluster: '{}')", cluster_name));
|
|
||||||
|
|
||||||
// Запуск HTTP/HTTPS серверов в отдельных задачах, если настроены
|
|
||||||
if self.http_enabled {
|
|
||||||
// ЗАПУСКАЕМ СЕРВЕРЫ В ФОНОВЫХ ЗАДАЧАХ, НЕ БЛОКИРУЯ ОСНОВНОЙ ПОТОК
|
|
||||||
self.start_http_servers_in_background().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_in_background(&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(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Запуск 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();
|
|
||||||
|
|
||||||
// ЗАПУСКАЕМ В ФОНОВОЙ ЗАДАЧЕ БЕЗ ОЖИДАНИЯ
|
|
||||||
tokio::spawn(async move {
|
|
||||||
// ИЗМЕНЕНИЕ: Убрано многоточие
|
|
||||||
println!("Starting HTTP server on {}", http_addr);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} 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();
|
|
||||||
|
|
||||||
// ЗАПУСКАЕМ В ФОНОВОЙ ЗАДАЧЕ БЕЗ ОЖИДАНИЯ
|
|
||||||
tokio::spawn(async move {
|
|
||||||
// ИЗМЕНЕНИЕ: Убрано многоточие
|
|
||||||
println!("Starting HTTPS server on {}", https_addr);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if !self.config.tls.enabled {
|
|
||||||
println!("HTTPS disabled: TLS not enabled in configuration");
|
|
||||||
} else {
|
|
||||||
println!("HTTPS server disabled in configuration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Получение менеджера шардинга (для тестов и расширений)
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn get_sharding_manager(&self) -> Arc<sharding::ShardingManager> {
|
|
||||||
self.sharding_manager.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Получение менеджера CSV (для тестов и расширений)
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn get_csv_manager(&self) -> Arc<csv_import_export::CsvManager> {
|
|
||||||
self.csv_manager.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user