From c3a9aa8af5cb0574f053056f0c68fdefb54f316e 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:29:03 +0000 Subject: [PATCH] Upload files to "src/common" --- src/common/mod.rs | 668 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 668 insertions(+) create mode 100644 src/common/mod.rs diff --git a/src/common/mod.rs b/src/common/mod.rs new file mode 100644 index 0000000..d286030 --- /dev/null +++ b/src/common/mod.rs @@ -0,0 +1,668 @@ +// src/common/mod.rs +//! Общие модули для Futriix с lock-free архитектурой +//! +//! Этот модуль содержит общие структуры, ошибки и утилиты, используемые +//! во всей системе Futriix. Основные компоненты: +//! - Типы ошибок с подробным описанием +//! - Конфигурацию системы в формате TOML +//! - Протокол обмена данными между компонентами +//! - Сериализацию/десериализацию сообщений +//! +//! Особенности: +//! - Единая система обработки ошибок через enum FutriixError +//! - Конфигурация с значениями по умолчанию +//! - Wait-free сериализация с MessagePack +//! - Поддержка всех компонентов системы + +use thiserror::Error; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::Path; + +/// Основной тип ошибки для Futriix +/// Используется для унифицированной обработки ошибок во всех компонентах системы +/// Каждый вариант содержит человеко-читаемое описание ошибки +#[derive(Error, Debug)] +pub enum FutriixError { + #[error("Configuration error: {0}")] + ConfigError(String), + + #[error("Database error: {0}")] + DatabaseError(String), + + #[error("Lua error: {0}")] + LuaError(String), + + #[error("Network error: {0}")] + NetworkError(String), + + #[error("Replication error: {0}")] + ReplicationError(String), + + #[error("HTTP error: {0}")] + HttpError(String), + + #[error("Serialization error: {0}")] + SerializationError(String), + + #[error("IO error: {0}")] + IoError(#[from] std::io::Error), + + #[error("CSV error: {0}")] + CsvError(String), + + #[error("Sharding error: {0}")] + ShardingError(String), + + #[error("Transaction error: {0}")] + TransactionError(String), + + #[error("STM error: {0}")] + StmError(String), + + #[error("Lock-free error: {0}")] + LockFreeError(String), + + #[error("Unknown error: {0}")] + Unknown(String), +} + +// Реализация преобразования из rlua::Error в FutriixError +// Позволяет использовать ошибки Lua в системе Futriix +impl From for FutriixError { + fn from(error: rlua::Error) -> Self { + FutriixError::LuaError(error.to_string()) + } +} + +// Реализация преобразования из serde_json::Error в FutriixError +// Позволяет использовать ошибки JSON сериализации в системе Futriix +impl From for FutriixError { + fn from(error: serde_json::Error) -> Self { + FutriixError::SerializationError(error.to_string()) + } +} + +// Реализация преобразования из csv::Error в FutriixError +// Позволяет использовать ошибки CSV обработки в системе Futriix +impl From for FutriixError { + fn from(error: csv::Error) -> Self { + FutriixError::CsvError(error.to_string()) + } +} + +/// Тип результата для Futriix +/// Сокращение для Result используется во всей системе +pub type Result = std::result::Result; + +// Модуль конфигурации +// Содержит структуры для загрузки и сохранения конфигурации в формате TOML +pub mod config { + use super::*; + + /// Основная конфигурация сервера Futriix + /// Содержит все настройки для всех компонентов системы + /// Значения по умолчанию обеспечивают работу системы "из коробки" + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct Config { + #[serde(default = "ServerConfig::default")] + pub server: ServerConfig, + #[serde(default = "ReplicationConfig::default")] + pub replication: ReplicationConfig, + #[serde(default = "ClusterConfig::default")] + pub cluster: ClusterConfig, + #[serde(default = "LuaConfig::default")] + pub lua: LuaConfig, + #[serde(default = "AclConfig::default")] + pub acl: AclConfig, + #[serde(default = "TlsConfig::default")] + pub tls: TlsConfig, + #[serde(default = "CsvConfig::default")] + pub csv: CsvConfig, + #[serde(default = "ShardingConfig::default")] + pub sharding: ShardingConfig, + } + + /// Конфигурация серверных параметров + /// Определяет сетевые настройки, порты и протоколы + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct ServerConfig { + #[serde(default = "default_host")] + pub host: String, + #[serde(default = "default_port")] + pub port: u16, + #[serde(default)] + pub http_port: Option, + #[serde(default)] + pub https_port: Option, + #[serde(default)] + pub http2_enabled: Option, + #[serde(default = "default_http_enabled")] + pub http: bool, + #[serde(default = "default_https_enabled")] + pub https: bool, + } + + /// Конфигурация репликации данных + /// Определяет параметры синхронизации между узлами кластера + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct ReplicationConfig { + #[serde(default)] + pub enabled: bool, + #[serde(default = "default_master_nodes")] + pub master_nodes: Vec, + #[serde(default = "default_sync_interval")] + pub sync_interval: u64, + } + + /// Конфигурация кластера + /// Определяет параметры распределенной работы системы + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct ClusterConfig { + #[serde(default)] + pub enabled: bool, + #[serde(default = "default_cluster_name")] + pub name: String, + } + + /// Конфигурация Lua скриптов + /// Определяет директории и скрипты для автоматического выполнения + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct LuaConfig { + #[serde(default = "default_scripts_dir")] + pub scripts_dir: String, + #[serde(default)] + pub auto_execute: Vec, + } + + /// Конфигурация Access Control List (ACL) + /// Позволяет управлять доступом к API по IP-адресам + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct AclConfig { + #[serde(default)] + pub enabled: bool, + #[serde(default = "default_allowed_ips")] + pub allowed_ips: Vec, + #[serde(default)] + pub denied_ips: Vec, + } + + /// Конфигурация TLS для HTTPS + /// Определяет пути к сертификатам и ключам для безопасного соединения + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct TlsConfig { + #[serde(default)] + pub enabled: bool, + #[serde(default = "default_cert_path")] + pub cert_path: String, + #[serde(default = "default_key_path")] + pub key_path: String, + } + + /// Конфигурация CSV операций + /// Определяет параметры импорта/экспорта данных в формате CSV + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct CsvConfig { + #[serde(default = "default_csv_import_dir")] + pub import_dir: String, + #[serde(default = "default_csv_export_dir")] + pub export_dir: String, + #[serde(default = "default_max_csv_file_size")] + pub max_file_size: u64, + } + + /// Конфигурация шардинга данных + /// Определяет параметры распределения данных по узлам кластера + #[derive(Debug, Serialize, Deserialize, Clone)] + pub struct ShardingConfig { + #[serde(default = "default_sharding_enabled")] + pub enabled: bool, + #[serde(default = "default_virtual_nodes_per_node")] + pub virtual_nodes_per_node: usize, + #[serde(default = "default_min_nodes_for_cluster")] + pub min_nodes_for_cluster: usize, + } + + // Функции для значений по умолчанию + // Используются для инициализации конфигурации, когда значения не указаны + + fn default_host() -> String { + "127.0.0.1".to_string() + } + + fn default_port() -> u16 { + 8081 + } + + fn default_http_enabled() -> bool { + true + } + + fn default_https_enabled() -> bool { + false + } + + fn default_master_nodes() -> Vec { + vec!["127.0.0.1:8081".to_string(), "127.0.0.1:8083".to_string()] + } + + fn default_sync_interval() -> u64 { + 5000 + } + + fn default_cluster_name() -> String { + "futriix-default-cluster".to_string() + } + + fn default_scripts_dir() -> String { + "lua_scripts".to_string() + } + + fn default_allowed_ips() -> Vec { + vec!["127.0.0.1".to_string(), "::1".to_string()] + } + + fn default_cert_path() -> String { + "certs/cert.pem".to_string() + } + + fn default_key_path() -> String { + "certs/key.pem".to_string() + } + + fn default_csv_import_dir() -> String { + "./futriix_csv/import".to_string() + } + + fn default_csv_export_dir() -> String { + "./futriix_csv/export".to_string() + } + + fn default_max_csv_file_size() -> u64 { + 104857600 // 100MB + } + + fn default_sharding_enabled() -> bool { + false + } + + fn default_virtual_nodes_per_node() -> usize { + 160 + } + + fn default_min_nodes_for_cluster() -> usize { + 3 + } + + // Реализации Default для всех конфигурационных структур + // Обеспечивают создание конфигурации с разумными значениями по умолчанию + + impl Default for ServerConfig { + fn default() -> Self { + Self { + host: default_host(), + port: default_port(), + http_port: Some(8082), + https_port: None, + http2_enabled: Some(false), + http: default_http_enabled(), + https: default_https_enabled(), + } + } + } + + impl Default for ReplicationConfig { + fn default() -> Self { + Self { + enabled: false, + master_nodes: default_master_nodes(), + sync_interval: default_sync_interval(), + } + } + } + + impl Default for ClusterConfig { + fn default() -> Self { + Self { + enabled: false, + name: default_cluster_name(), + } + } + } + + impl Default for LuaConfig { + fn default() -> Self { + Self { + scripts_dir: default_scripts_dir(), + auto_execute: vec!["init.lua".to_string()], + } + } + } + + impl Default for AclConfig { + fn default() -> Self { + Self { + enabled: false, + allowed_ips: default_allowed_ips(), + denied_ips: vec![], + } + } + } + + impl Default for TlsConfig { + fn default() -> Self { + Self { + enabled: false, + cert_path: default_cert_path(), + key_path: default_key_path(), + } + } + } + + impl Default for CsvConfig { + fn default() -> Self { + Self { + import_dir: default_csv_import_dir(), + export_dir: default_csv_export_dir(), + max_file_size: default_max_csv_file_size(), + } + } + } + + impl Default for ShardingConfig { + fn default() -> Self { + Self { + enabled: default_sharding_enabled(), + virtual_nodes_per_node: default_virtual_nodes_per_node(), + min_nodes_for_cluster: default_min_nodes_for_cluster(), + } + } + } + + impl Default for Config { + fn default() -> Self { + Self { + server: ServerConfig::default(), + replication: ReplicationConfig::default(), + cluster: ClusterConfig::default(), + lua: LuaConfig::default(), + acl: AclConfig::default(), + tls: TlsConfig::default(), + csv: CsvConfig::default(), + sharding: ShardingConfig::default(), + } + } + } + + impl Config { + /// Загрузка конфигурации из файла TOML + /// Если файл не существует, создается конфигурация с значениями по умолчанию + pub fn load(path: &str) -> Result { + let path = Path::new(path); + + if !path.exists() { + let default_config = Config::default(); + let toml_content = toml::to_string_pretty(&default_config) + .map_err(|e| FutriixError::ConfigError(e.to_string()))?; + + fs::write(path, toml_content) + .map_err(|e| FutriixError::ConfigError(e.to_string()))?; + + println!("Created default configuration file: {}", path.display()); + return Ok(default_config); + } + + let content = fs::read_to_string(path) + .map_err(|e| FutriixError::ConfigError(e.to_string()))?; + + let mut config: Config = toml::from_str(&content) + .map_err(|e| FutriixError::ConfigError(e.to_string()))?; + + // Заполняем значения по умолчанию для пустых полей + if config.server.host.is_empty() { + config.server.host = default_host(); + } + if config.server.port == 0 { + config.server.port = default_port(); + } + if config.replication.master_nodes.is_empty() { + config.replication.master_nodes = default_master_nodes(); + } + if config.replication.sync_interval == 0 { + config.replication.sync_interval = default_sync_interval(); + } + if config.cluster.name.is_empty() { + config.cluster.name = default_cluster_name(); + } + if config.lua.scripts_dir.is_empty() { + config.lua.scripts_dir = default_scripts_dir(); + } + if config.acl.allowed_ips.is_empty() { + config.acl.allowed_ips = default_allowed_ips(); + } + if config.tls.cert_path.is_empty() { + config.tls.cert_path = default_cert_path(); + } + if config.tls.key_path.is_empty() { + config.tls.key_path = default_key_path(); + } + if config.csv.import_dir.is_empty() { + config.csv.import_dir = default_csv_import_dir(); + } + if config.csv.export_dir.is_empty() { + config.csv.export_dir = default_csv_export_dir(); + } + if config.csv.max_file_size == 0 { + config.csv.max_file_size = default_max_csv_file_size(); + } + if config.sharding.virtual_nodes_per_node == 0 { + config.sharding.virtual_nodes_per_node = default_virtual_nodes_per_node(); + } + if config.sharding.min_nodes_for_cluster == 0 { + config.sharding.min_nodes_for_cluster = default_min_nodes_for_cluster(); + } + + Ok(config) + } + + /// Сохранение конфигурации в файл TOML + #[allow(dead_code)] + pub fn save(&self, path: &str) -> Result<()> { + let toml_content = toml::to_string_pretty(self) + .map_err(|e| FutriixError::ConfigError(e.to_string()))?; + + fs::write(path, toml_content) + .map_err(|e| FutriixError::ConfigError(e.to_string())) + } + } +} + +// Модуль протокола обмена данными +// Содержит структуры для сериализации команд и ответов между компонентами системы +pub mod protocol { + use serde::{Deserialize, Serialize}; + + /// Команды для выполнения в базе данных + /// Используются для передачи операций между клиентами и сервером + /// Поддерживают все CRUD операции, транзакции, индексы и шардинг + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum Command { + Create { + collection: String, + document: Vec, + }, + Read { + collection: String, + id: String, + }, + Update { + collection: String, + id: String, + document: Vec, + }, + Delete { + collection: String, + id: String, + }, + Query { + collection: String, + filter: Vec, + }, + + CreateProcedure { + name: String, + code: Vec, + }, + CallProcedure { + name: String, + }, + BeginTransaction { + transaction_id: String, + }, + CommitTransaction { + transaction_id: String, + }, + RollbackTransaction { + transaction_id: String, + }, + + CreateIndex { + collection: String, + index: crate::server::database::Index, + }, + QueryByIndex { + collection: String, + index_name: String, + value: Vec, + }, + + AddShardNode { + node_id: String, + address: String, + capacity: u64, + }, + RemoveShardNode { + node_id: String, + }, + MigrateShard { + collection: String, + from_node: String, + to_node: String, + shard_key: String, + }, + RebalanceCluster, + GetClusterStatus, + StartElection, + GetRaftNodes, + + AddConstraint { + collection: String, + constraint_name: String, + constraint_type: String, + field: String, + value: Vec, + }, + RemoveConstraint { + collection: String, + constraint_name: String, + }, + + EnableCompression { + collection: String, + algorithm: String, + }, + DisableCompression { + collection: String, + }, + + CreateGlobalIndex { + name: String, + field: String, + unique: bool, + }, + QueryGlobalIndex { + index_name: String, + value: Vec, + }, + + ImportCsv { + collection: String, + file_path: String, + }, + ExportCsv { + collection: String, + file_path: String, + }, + ListCsvFiles, + GetImportProgress { + collection: String, + }, + } + + /// Ответы от базы данных + /// Используются для возврата результатов выполнения команд + /// Могут содержать данные об успехе или ошибке + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum Response { + Success(Vec), + Error(String), + } + + /// Сообщение для репликации данных между узлами + /// Содержит команду, последовательный номер и временную метку + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ReplicationMessage { + pub sequence: u64, + pub command: Command, + pub timestamp: i64, + } + + /// Структура для информации о шарде + /// Используется для мониторинга состояния распределенной системы + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ShardInfo { + pub node_id: String, + pub address: String, + pub capacity: u64, + pub used: u64, + pub collections: Vec, + } + + /// Структура для информации о Raft узле + /// Используется для мониторинга консенсуса в распределенной системе + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct RaftNodeInfo { + pub node_id: String, + pub address: String, + pub state: String, + pub term: u64, + pub last_heartbeat: i64, + } + + /// Структура для статуса кластера + /// Содержит полную информацию о состоянии распределенной системы + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ClusterStatus { + pub nodes: Vec, + pub total_capacity: u64, + pub total_used: u64, + pub rebalance_needed: bool, + pub cluster_formed: bool, + pub leader_exists: bool, + pub raft_nodes: Vec, + } + + /// Wait-Free сериализация сообщений с использованием MessagePack + /// Обеспечивает высокую производительность и компактный размер сообщений + pub fn serialize(value: &T) -> crate::common::Result> { + rmp_serde::to_vec(value) + .map_err(|e| crate::common::FutriixError::SerializationError(e.to_string())) + } + + /// Wait-Free десериализация сообщений с использованием MessagePack + /// Обратная операция для сериализации + pub fn deserialize<'a, T: serde::Deserialize<'a>>(bytes: &'a [u8]) -> crate::common::Result { + rmp_serde::from_slice(bytes) + .map_err(|e| crate::common::FutriixError::SerializationError(e.to_string())) + } +}