Delete src/common/44mod.rs

This commit is contained in:
Григорий Сафронов 2025-12-19 19:56:36 +00:00
parent 2acdd60d43
commit af1d81902b

View File

@ -1,628 +0,0 @@
// src/common/mod.rs
//! Общие модули для Futriix
//!
//! Содержит общие структуры данных, ошибки, протоколы и конфигурацию,
//! используемые во всех компонентах системы с wait-free архитектурой.
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("Unknown error: {0}")]
Unknown(String),
}
// Реализация преобразования из rlua::Error в FutriixError
impl From<rlua::Error> for FutriixError {
fn from(error: rlua::Error) -> Self {
FutriixError::LuaError(error.to_string())
}
}
// Реализация преобразования из serde_json::Error в FutriixError
impl From<serde_json::Error> for FutriixError {
fn from(error: serde_json::Error) -> Self {
FutriixError::SerializationError(error.to_string())
}
}
// Реализация преобразования из csv::Error в FutriixError
impl From<csv::Error> for FutriixError {
fn from(error: csv::Error) -> Self {
FutriixError::CsvError(error.to_string())
}
}
/// Тип результата для Futriix
pub type Result<T> = std::result::Result<T, FutriixError>;
// Модуль конфигурации
pub mod config {
use super::*;
/// Конфигурация сервера
#[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<u16>,
#[serde(default)]
pub https_port: Option<u16>,
#[serde(default)]
pub http2_enabled: Option<bool>,
#[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<String>,
#[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<String>,
}
/// Конфигурация ACL
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AclConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_allowed_ips")]
pub allowed_ips: Vec<String>,
#[serde(default)]
pub denied_ips: Vec<String>,
}
/// Конфигурация TLS
#[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
#[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<String> {
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<String> {
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
}
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 {
/// Загрузка конфигурации из файла
pub fn load(path: &str) -> Result<Self> {
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)
}
/// Сохранение конфигурации в файл
#[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};
/// Команды для выполнения в базе данных
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Command {
// Базовые CRUD команды
Create {
collection: String,
document: Vec<u8>,
},
Read {
collection: String,
id: String,
},
Update {
collection: String,
id: String,
document: Vec<u8>,
},
Delete {
collection: String,
id: String,
},
Query {
collection: String,
filter: Vec<u8>,
},
// Команды для процедур и транзакций
CreateProcedure {
name: String,
code: Vec<u8>,
},
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<u8>,
},
// Команды для шардинга с Raft
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, // Новая команда для Raft выборов
GetRaftNodes, // Новая команда для получения Raft узлов
// Команды для constraints
AddConstraint {
collection: String,
constraint_name: String,
constraint_type: String,
field: String,
value: Vec<u8>,
},
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<u8>,
},
// Новые команды для CSV импорта/экспорта
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<u8>),
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<String>,
}
/// Структура для информации о Raft узле
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RaftNodeInfo {
pub node_id: String,
pub address: String,
pub state: String, // "leader", "follower", "candidate"
pub term: u64,
pub last_heartbeat: i64,
}
/// Структура для статуса кластера
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClusterStatus {
pub nodes: Vec<ShardInfo>,
pub total_capacity: u64,
pub total_used: u64,
pub rebalance_needed: bool,
pub cluster_formed: bool, // Новое поле: собран ли кластер
pub leader_exists: bool, // Новое поле: существует ли лидер
pub raft_nodes: Vec<RaftNodeInfo>, // Новое поле: список Raft узлов
}
/// Wait-Free сериализация сообщений
pub fn serialize<T: serde::Serialize>(value: &T) -> crate::common::Result<Vec<u8>> {
rmp_serde::to_vec(value)
.map_err(|e| crate::common::FutriixError::SerializationError(e.to_string()))
}
/// Wait-Free десериализация сообщений
pub fn deserialize<'a, T: serde::Deserialize<'a>>(bytes: &'a [u8]) -> crate::common::Result<T> {
rmp_serde::from_slice(bytes)
.map_err(|e| crate::common::FutriixError::SerializationError(e.to_string()))
}
}