From 499d1f644aba916c78835fd258a9e20a734bbffc 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: Fri, 31 Jul 2026 11:58:21 +0000 Subject: [PATCH] Upload files to "internal/config" --- internal/config/config.go | 2404 +++++++++++++++++++++++++++++++++++++ 1 file changed, 2404 insertions(+) create mode 100644 internal/config/config.go diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..bfca861 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,2404 @@ +/* + * Copyright 2026 Safronov Grigorii + * + * Licensed under the CDDL, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * https://opensource.org/licenses/CDDL-1.0 + */ + +// Файл: internal/config/config.go +// Назначение: Загрузка и парсинг TOML-конфигурации, валидация параметров, +// предоставление доступа к настройкам кластера, хранилища и REPL. +// +// Данный пакет отвечает за: +// - Чтение конфигурационного файла в формате TOML +// - Установку значений по умолчанию для всех параметров +// - Валидацию корректности настроек +// - Предоставление типобезопасного доступа к конфигурации через методы-геттеры + +package config + +import ( + "fmt" + "strings" + "time" + + "github.com/BurntSushi/toml" +) + +// ============================================================================= +// ОСНОВНАЯ СТРУКТУРА КОНФИГУРАЦИИ +// ============================================================================= + +// Config представляет собой корневую структуру конфигурации, +// объединяющую все подсистемы приложения. +// Каждое поле соответствует секции в TOML-файле. +type Config struct { + Cluster ClusterConfig `toml:"cluster"` // Настройки кластеризации (Raft, узлы) + Storage StorageConfig `toml:"storage"` // Настройки хранилища (движки, ограничения) + Repl ReplConfig `toml:"repl"` // Настройки REPL (интерактивной оболочки) + Log LogConfig `toml:"log"` // Настройки логирования + API APIConfig `toml:"api"` // Настройки HTTP API + Replication ReplicationConfig `toml:"replication"` // Настройки репликации + Plugins PluginsConfig `toml:"plugins"` // Настройки системы плагинов (Lua) + Compression CompressionConfig `toml:"compression"` // Настройки сжатия данных + WebUI WebUIConfig `toml:"webui"` // Настройки веб-интерфейса + Performance PerformanceConfig `toml:"performance"` // Настройки производительности + Security SecurityConfig `toml:"security"` // Настройки безопасности (TLS) + Monitoring MonitoringConfig `toml:"monitoring"` // Настройки мониторинга (метрики, трассировка) + Recovery RecoveryConfig `toml:"recovery"` // Настройки восстановления после сбоев + WAL WALConfig `toml:"wal"` // Настройки WAL (Write-Ahead Log) + MVCC MVCCConfig `toml:"mvcc"` // Настройки MVCC (Multi-Version Concurrency Control) + Transactions TransactionsConfig `toml:"transactions"` // Настройки транзакций + Saga SagaConfig `toml:"saga"` // Настройки SAGA оркестратора + ACL ACLConfig `toml:"acl"` // Настройки ACL (Access Control List) + ClusterTLS TLSConfig `toml:"cluster_tls"` // Настройки TLS для кластерного взаимодействия + Backpressure BackpressureConfig `toml:"backpressure"` // Настройки механизма обратного давления + RuntimeLimits RuntimeLimitsConfig `toml:"runtime_limits"` // Ограничения времени выполнения + Autoscaling AutoscalingConfig `toml:"autoscaling"` // Настройки автоматического масштабирования + SchemaMigration SchemaMigrationConfig `toml:"schema_migration"` // Настройки миграции схемы + Backup BackupConfig `toml:"backup"` // Настройки резервного копирования + Engines EnginesConfig `toml:"engines"` // Настройки движков хранения + Migration MigrationConfig `toml:"migration"` // Настройки кросс-датацентровой миграции +} + +// ============================================================================= +// КОНФИГУРАЦИЯ КЛАСТЕРА +// ============================================================================= + +// ClusterConfig содержит настройки для работы в кластерном режиме +// на основе протокола Raft для обеспечения согласованности. +type ClusterConfig struct { + // Имя кластера - идентификатор для группировки узлов + Name string `toml:"name"` + + // Сетевые настройки узла + NodeIP string `toml:"node_ip"` // IP-адрес для прослушивания + NodePort int `toml:"node_port"` // Порт для клиентских подключений + RaftPort int `toml:"raft_port"` // Порт для Raft-коммуникации + + // Настройки Raft + RaftDataDir string `toml:"raft_data_dir"` // Директория для хранения Raft-лога + Bootstrap bool `toml:"bootstrap"` // Является ли узел инициализатором кластера + Nodes []string `toml:"nodes"` // Список адресов других узлов кластера + + // Таймауты Raft (в миллисекундах) + HeartbeatTimeoutMs int `toml:"heartbeat_timeout_ms"` // Интервал отправки heartbeat + ElectionTimeoutMs int `toml:"election_timeout_ms"` // Таймаут для начала выборов + CommitTimeoutMs int `toml:"commit_timeout_ms"` // Таймаут коммита записей + + // Настройки снэпшотов + SnapshotIntervalMin int `toml:"snapshot_interval_min"` // Интервал создания снэпшотов (минуты) + SnapshotThreshold int `toml:"snapshot_threshold"` // Количество записей для создания снэпшота + + // Защита от split-brain и восстановление + SplitBrainPrevention bool `toml:"split_brain_prevention"` // Включить защиту от разделения кластера + RecoveryTimeoutSec int `toml:"recovery_timeout_sec"` // Таймаут восстановления после сбоя + + // Географические настройки для оптимизации маршрутизации + Region string `toml:"region"` // Регион расположения узла + PriorityZone int `toml:"priority_zone"` // Приоритетная зона (0-9, где 9 - наивысший) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ SAGA ОРКЕСТРАТОРА +// ============================================================================= + +// SagaConfig содержит настройки отказоустойчивого оркестратора распределённых транзакций. +// Обеспечивает выполнение длительных транзакций с компенсацией шагов по протоколу SAGA. +type SagaConfig struct { + // Основные настройки + Enabled bool `toml:"enabled"` // Включить SAGA оркестратор + CoordinatorCount int `toml:"coordinator_count"` // Количество координаторов (>= 3 для отказоустойчивости) + StateDir string `toml:"state_dir"` // Директория для хранения состояний SAGA + + // Настройки выполнения + MaxRetries int `toml:"max_retries"` // Максимальное количество попыток выполнения шага + RetryBackoffMs int `toml:"retry_backoff_ms"` // Базовая задержка между повторными попытками (мс) + SagaTimeoutSec int `toml:"saga_timeout_sec"` // Таймаут выполнения SAGA (сек) + StuckCheckIntervalSec int `toml:"stuck_check_interval_sec"` // Интервал проверки зависших SAGA (сек) + + // Настройки оркестрации + LeaderElectionIntervalSec int `toml:"leader_election_interval_sec"` // Интервал выбора лидера (сек) + RecoveryIntervalSec int `toml:"recovery_interval_sec"` // Интервал восстановления незавершённых SAGA (сек) + MetricsIntervalSec int `toml:"metrics_interval_sec"` // Интервал сбора метрик (сек) + + // Настройки очистки и кэширования + CleanupPeriodHours int `toml:"cleanup_period_hours"` // Период очистки старых SAGA (часы) + MaxCacheSize int `toml:"max_cache_size"` // Максимальное количество состояний в кэше + OperationRetentionDays int `toml:"operation_retention_days"` // Время жизни выполненных операций (дни) + + // Настройки производительности + ChannelBufferSize int `toml:"channel_buffer_size"` // Размер буфера каналов + AsyncRecoveryWorkers int `toml:"async_recovery_workers"` // Количество воркеров для асинхронного восстановления + AsyncRecoveryTimeoutSec int `toml:"async_recovery_timeout_sec"` // Таймаут асинхронного восстановления (сек) + + // Настройки синхронизации с диском + FsyncEnabled bool `toml:"fsync_enabled"` // Принудительная синхронизация с диском + FsyncMaxRetries int `toml:"fsync_max_retries"` // Количество повторных попыток синхронизации + FsyncRetryDelayMs int `toml:"fsync_retry_delay_ms"` // Задержка между повторными попытками (мс) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ХРАНИЛИЩА +// ============================================================================= + +// StorageConfig содержит настройки системы хранения данных. +type StorageConfig struct { + PageSizeMB int `toml:"page_size_mb"` // Размер страницы памяти в МБ + MaxCollections int `toml:"max_collections"` // Максимальное количество коллекций + MaxDocumentsPerCollection int `toml:"max_documents_per_collection"` // Макс. документов в коллекции + DefaultEngine string `toml:"default_engine"` // Движок по умолчанию + EnableCustomEngines bool `toml:"enable_custom_engines"` // Включить пользовательские движки +} + +// ============================================================================= +// КОНФИГУРАЦИЯ REPL (ИНТЕРАКТИВНАЯ ОБОЛОЧКА) +// ============================================================================= + +// ReplConfig содержит настройки интерактивной командной оболочки. +type ReplConfig struct { + PromptColor string `toml:"prompt_color"` // Цвет приглашения ввода + HistorySize int `toml:"history_size"` // Размер истории команд +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ЛОГИРОВАНИЯ +// ============================================================================= + +// LogConfig содержит настройки системы логирования. +type LogConfig struct { + LogFile string `toml:"log_file"` // Путь к файлу лога (пусто = stdout) + LogLevel string `toml:"log_level"` // Уровень логирования (debug, info, warn, error) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ HTTP API +// ============================================================================= + +// APIConfig содержит настройки HTTP API сервера. +type APIConfig struct { + Port int `toml:"port"` // Порт для HTTP API +} + +// ============================================================================= +// КОНФИГУРАЦИЯ РЕПЛИКАЦИИ +// ============================================================================= + +// ReplicationConfig содержит настройки репликации данных между узлами. +type ReplicationConfig struct { + Enabled bool `toml:"enabled"` // Включена ли репликация + SyncReplication bool `toml:"sync_replication"` // Синхронная репликация + ReplicationTimeoutMs int `toml:"replication_timeout_ms"` // Таймаут репликации (мс) + MaxReplicaLagMs int `toml:"max_replica_lag_ms"` // Максимальное отставание реплики (мс) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ПЛАГИНОВ (LUA) +// ============================================================================= + +// PluginsConfig содержит настройки системы выполнения Lua-скриптов. +type PluginsConfig struct { + Enabled bool `toml:"enabled"` // Включена ли поддержка плагинов + ScriptDir string `toml:"script_dir"` // Директория со скриптами + AllowList []string `toml:"allow_list"` // Белый список разрешенных скриптов + MaxCPUTimeMs int `toml:"max_cpu_time_ms"` // Макс. время CPU (мс) + MaxMemoryMB int `toml:"max_memory_mb"` // Макс. память (МБ) + MaxExecutionTimeSec int `toml:"max_execution_time_sec"` // Макс. время выполнения (сек) + MaxInstructions int64 `toml:"max_instructions"` // Макс. количество инструкций + HotReloadIntervalSec int `toml:"hot_reload_interval_sec"` // Интервал горячей перезагрузки + MaxEventLogSize int `toml:"max_event_log_size"` // Макс. размер лога событий + LoadTimeoutSec int `toml:"load_timeout_sec"` // Таймаут загрузки скрипта + MaxLuaStates int `toml:"max_lua_states"` // Макс. количество Lua-состояний + LuaStateTTLSec int `toml:"lua_state_ttl_sec"` // TTL Lua-состояния + EnginePluginDir string `toml:"engine_plugin_dir"` // Директория плагинов движков +} + +// ============================================================================= +// КОНФИГУРАЦИЯ СЖАТИЯ +// ============================================================================= + +// CompressionConfig содержит настройки сжатия данных. +type CompressionConfig struct { + Enabled bool `toml:"enabled"` // Включено ли сжатие + Algorithm string `toml:"algorithm"` // Алгоритм сжатия (snappy, lz4, zstd) + Level int `toml:"level"` // Уровень сжатия (1-9) + MinSize int `toml:"min_size"` // Минимальный размер для сжатия (байт) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ВЕБ-ИНТЕРФЕЙСА +// ============================================================================= + +// WebUIConfig содержит настройки встроенного веб-интерфейса. +type WebUIConfig struct { + Enabled bool `toml:"enabled"` // Включен ли веб-интерфейс + Port int `toml:"port"` // Порт для веб-интерфейса + Theme string `toml:"theme"` // Тема оформления (dark, light) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ПРОИЗВОДИТЕЛЬНОСТИ +// ============================================================================= + +// PerformanceConfig содержит настройки, влияющие на производительность системы. +type PerformanceConfig struct { + EnablePipeline bool `toml:"enable_pipeline"` // Включить конвейерную обработку + BatchSize int `toml:"batch_size"` // Размер пакета для пакетных операций + ReadFromFollower bool `toml:"read_from_follower"` // Читать с ведомых узлов + MaxConnections int `toml:"max_connections"` // Максимальное количество соединений + ReadReplicaDelayMs int `toml:"read_replica_delay_ms"` // Задержка чтения с реплики (мс) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ БЕЗОПАСНОСТИ +// ============================================================================= + +// SecurityConfig содержит настройки безопасности (TLS). +type SecurityConfig struct { + EnableTLS bool `toml:"enable_tls"` // Включен ли TLS + CertFile string `toml:"cert_file"` // Путь к сертификату + KeyFile string `toml:"key_file"` // Путь к приватному ключу + CAFile string `toml:"ca_file"` // Путь к корневому сертификату CA + MinVersion string `toml:"min_version"` // Минимальная версия TLS (1.0, 1.1, 1.2, 1.3) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ МОНИТОРИНГА +// ============================================================================= + +// MonitoringConfig содержит настройки мониторинга и наблюдаемости. +type MonitoringConfig struct { + EnableMetrics bool `toml:"enable_metrics"` // Включить сбор метрик + MetricsPort int `toml:"metrics_port"` // Порт для экспорта метрик (Prometheus) + EnableTracing bool `toml:"enable_tracing"` // Включить распределённую трассировку + TraceSampleRate float64 `toml:"trace_sample_rate"` // Частота сэмплирования трассировки (0-1) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ВОССТАНОВЛЕНИЯ +// ============================================================================= + +// RecoveryConfig содержит настройки восстановления после сбоев. +type RecoveryConfig struct { + AutoRejoin bool `toml:"auto_rejoin"` // Автоматическое переподключение + MaxRetrySec int `toml:"max_retry_sec"` // Макс. время повторных попыток + DataReplicationTimeoutSec int `toml:"data_replication_timeout_sec"` // Таймаут репликации данных + StaleReadTimeoutSec int `toml:"stale_read_timeout_sec"` // Таймаут устаревшего чтения +} + +// ============================================================================= +// КОНФИГУРАЦИЯ WAL (WRITE-AHEAD LOG) +// ============================================================================= + +// WALConfig содержит настройки журнала упреждающей записи. +// WAL обеспечивает durability и используется для восстановления после сбоев. +type WALConfig struct { + SegmentSizeMB int `toml:"segment_size_mb"` // Размер сегмента WAL (МБ) + SyncIntervalSec int `toml:"sync_interval_sec"` // Интервал синхронизации на диск + BatchSize int `toml:"batch_size"` // Размер пакета для записи + RecoveryWorkers int `toml:"recovery_workers"` // Количество потоков восстановления + Enabled bool `toml:"enabled"` // Включен ли WAL + AsyncRecovery bool `toml:"async_recovery"` // Асинхронное восстановление + AsyncRecoveryWorkers int `toml:"async_recovery_workers"` // Потоков асинхронного восстановления + AsyncRecoveryBuffer int `toml:"async_recovery_buffer"` // Размер буфера асинхронного восстановления +} + +// ============================================================================= +// КОНФИГУРАЦИЯ MVCC (MULTI-VERSION CONCURRENCY CONTROL) +// ============================================================================= + +// MVCCConfig содержит настройки механизма многоверсионного контроля параллелизма. +// MVCC позволяет читать согласованные снимки данных без блокировок записи. +type MVCCConfig struct { + MaxVersionsPerDoc int `toml:"max_versions_per_doc"` // Макс. версий на документ + VisibilityMapSize int `toml:"visibility_map_size"` // Размер карты видимости + PruneIntervalMin int `toml:"prune_interval_min"` // Интервал очистки старых версий (минуты) + RetentionDays int `toml:"retention_days"` // Срок хранения старых версий (дни) + ReadCacheSize int `toml:"read_cache_size"` // Размер кэша чтения + ReadCacheTTLSec int `toml:"read_cache_ttl_sec"` // TTL кэша чтения (секунды) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ТРАНЗАКЦИЙ +// ============================================================================= + +// TransactionsConfig содержит настройки транзакционной подсистемы. +type TransactionsConfig struct { + DefaultTimeoutSec int `toml:"default_timeout_sec"` // Таймаут транзакции по умолчанию + DeadlockCheckIntervalSec int `toml:"deadlock_check_interval_sec"` // Интервал проверки deadlock + MaxSavepointsPerTx int `toml:"max_savepoints_per_tx"` // Макс. точек сохранения + Enabled bool `toml:"enabled"` // Включены ли транзакции + CheckpointIntervalSec int `toml:"checkpoint_interval_sec"` // Интервал контрольных точек +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ACL (ACCESS CONTROL LIST) +// ============================================================================= + +// ACLConfig содержит настройки контроля доступа. +type ACLConfig struct { + MaxDeniedLogSize int `toml:"max_denied_log_size"` // Макс. размер лога отказов + TemporaryGrantTTLHours int `toml:"temporary_grant_ttl_hours"` // TTL временных прав (часы) + EnableRoleHierarchy bool `toml:"enable_role_hierarchy"` // Иерархия ролей + CacheTTLSec int `toml:"cache_ttl_sec"` // TTL кэша ACL (сек) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ TLS ДЛЯ КЛАСТЕРА +// ============================================================================= + +// TLSConfig содержит настройки TLS для кластерного взаимодействия. +type TLSConfig struct { + Enabled bool `toml:"enabled"` // Включен ли TLS + CertFile string `toml:"cert_file"` // Путь к сертификату + KeyFile string `toml:"key_file"` // Путь к приватному ключу + CAFile string `toml:"ca_file"` // Путь к корневому сертификату CA + MinVersion string `toml:"min_version"` // Минимальная версия TLS + MutualAuth bool `toml:"mutual_auth"` // Взаимная аутентификация + KeyRotationDays int `toml:"key_rotation_days"` // Интервал ротации ключей + AutoGenerate bool `toml:"auto_generate"` // Автоматическая генерация сертификатов +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ОБРАТНОГО ДАВЛЕНИЯ (BACKPRESSURE) +// ============================================================================= + +// BackpressureConfig содержит настройки механизма обратного давления. +// Обратное давление защищает систему от перегрузки, ограничивая поступление запросов. +type BackpressureConfig struct { + Enabled bool `toml:"enabled"` // Включен ли механизм + CPUThreshold float64 `toml:"cpu_threshold"` // Порог CPU (0-1) + MemoryThreshold float64 `toml:"memory_threshold"` // Порог памяти (0-1) + QueueSizeThreshold int `toml:"queue_size_threshold"` // Порог размера очереди + ConnectionThreshold int `toml:"connection_threshold"` // Порог количества соединений + CheckIntervalMs int `toml:"check_interval_ms"` // Интервал проверки (мс) + LowDelayMs int64 `toml:"low_delay_ms"` // Задержка для низкой нагрузки (мс) + MediumRejectProb uint32 `toml:"medium_reject_prob"` // Вероятность отказа при средней нагрузке (%) + HighRejectProb uint32 `toml:"high_reject_prob"` // Вероятность отказа при высокой нагрузке (%) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ОГРАНИЧЕНИЙ ВРЕМЕНИ ВЫПОЛНЕНИЯ +// ============================================================================= + +// RuntimeLimitsConfig содержит глобальные ограничения для защиты от недобросовестных запросов. +type RuntimeLimitsConfig struct { + Enabled bool `toml:"enabled"` // Включены ли ограничения + GlobalMaxDocSizeMB int `toml:"global_max_doc_size_mb"` // Макс. размер документа (МБ) + GlobalMaxCollSizeMB int64 `toml:"global_max_coll_size_mb"` // Макс. размер коллекции (МБ) + GlobalMaxDocsPerColl int64 `toml:"global_max_docs_per_coll"` // Макс. документов в коллекции +} + +// ============================================================================= +// КОНФИГУРАЦИЯ АВТОМАСШТАБИРОВАНИЯ +// ============================================================================= + +// AutoscalingConfig содержит настройки автоматического масштабирования кластера. +type AutoscalingConfig struct { + Enabled bool `toml:"enabled"` // Включено ли автомасштабирование + MinNodes int `toml:"min_nodes"` // Минимальное количество узлов + MaxNodes int `toml:"max_nodes"` // Максимальное количество узлов + ScaleUpThreshold float64 `toml:"scale_up_threshold"` // Порог для увеличения (0-1) + ScaleDownThreshold float64 `toml:"scale_down_threshold"` // Порог для уменьшения (0-1) + ScaleUpCooldownSec int `toml:"scale_up_cooldown_sec"` // Задержка перед масштабированием вверх + ScaleDownCooldownSec int `toml:"scale_down_cooldown_sec"` // Задержка перед масштабированием вниз + EvaluationIntervalSec int `toml:"evaluation_interval_sec"` // Интервал оценки нагрузки + PredictiveEnabled bool `toml:"predictive_enabled"` // Прогнозирующее масштабирование + MaxScaleUpNodes int `toml:"max_scale_up_nodes"` // Макс. узлов при масштабировании вверх + MaxScaleDownNodes int `toml:"max_scale_down_nodes"` // Макс. узлов при масштабировании вниз +} + +// ============================================================================= +// КОНФИГУРАЦИЯ МИГРАЦИИ СХЕМЫ +// ============================================================================= + +// SchemaMigrationConfig содержит настройки миграции схемы данных. +type SchemaMigrationConfig struct { + Enabled bool `toml:"enabled"` // Включена ли миграция + MigrationDir string `toml:"migration_dir"` // Директория с миграциями + AutoMigrate bool `toml:"auto_migrate"` // Автоматическая миграция при старте + TargetVersion string `toml:"target_version"` // Целевая версия схемы +} + +// ============================================================================= +// КОНФИГУРАЦИЯ РЕЗЕРВНОГО КОПИРОВАНИЯ +// ============================================================================= + +// BackupConfig содержит настройки резервного копирования. +type BackupConfig struct { + Enabled bool `toml:"enabled"` // Включено ли резервное копирование + BackupDir string `toml:"backup_dir"` // Директория для бэкапов + MaxConcurrent int `toml:"max_concurrent"` // Макс. параллельных бэкапов + CompressEnabled bool `toml:"compress_enabled"` // Сжатие бэкапов + RetentionDays int `toml:"retention_days"` // Срок хранения бэкапов (дни) +} + +// ============================================================================= +// КОНФИГУРАЦИЯ ДВИЖКОВ ХРАНЕНИЯ +// ============================================================================= + +// EnginesConfig содержит настройки всех движков хранения данных. +// Каждый движок оптимизирован для определённого типа нагрузки. +type EnginesConfig struct { + Row EngineConfig `toml:"row"` // Строчный движок (по умолчанию) + Columnar EngineConfig `toml:"columnar"` // Колоночный движок (аналитика) + Document EngineConfig `toml:"document"` // Документоориентированный движок + KV EngineConfig `toml:"kv"` // Key-Value движок + TS EngineConfig `toml:"ts"` // Time-Series движок (временные ряды) + Graph EngineConfig `toml:"graph"` // Графовый движок +} + +// EngineConfig содержит настройки отдельного движка хранения. +type EngineConfig struct { + Enabled bool `toml:"enabled"` // Включен ли движок + Description string `toml:"description"` // Описание движка + Config map[string]interface{} `toml:"config"` // Дополнительные параметры движка +} + +// ============================================================================= +// КОНФИГУРАЦИЯ КРОСС-ДАТАЦЕНТРОВОЙ МИГРАЦИИ +// ============================================================================= + +// MigrationConfig представляет конфигурацию кросс-датацентровой миграции +type MigrationConfig struct { + Enabled bool `toml:"enabled"` + Mode string `toml:"mode"` // manual, semi_auto, auto + Source *DatacenterConfig `toml:"source"` + Target *DatacenterConfig `toml:"target"` + Settings *MigrationSettings `toml:"settings"` + Delta *DeltaSyncConfig `toml:"delta"` + Validation *ValidationConfig `toml:"validation"` +} + +// DatacenterConfig представляет конфигурацию датацентра +type DatacenterConfig struct { + Name string `toml:"name"` + Endpoint string `toml:"endpoint"` + APIKey string `toml:"api_key"` + TimeoutSec int `toml:"timeout_sec"` +} + +// MigrationSettings представляет настройки миграции +type MigrationSettings struct { + BatchSize int `toml:"batch_size"` + Workers int `toml:"workers"` + Compression string `toml:"compression"` + ResumeEnabled bool `toml:"resume_enabled"` + CheckpointIntervalSec int `toml:"checkpoint_interval_sec"` + MaxRetries int `toml:"max_retries"` + RetryBackoffSec int `toml:"retry_backoff_sec"` + Collections []string `toml:"collections"` + ExcludeCollections []string `toml:"exclude_collections"` +} + +// DeltaSyncConfig представляет конфигурацию дельта-синхронизации +type DeltaSyncConfig struct { + Enabled bool `toml:"enabled"` + IntervalSec int `toml:"interval_sec"` + MaxLagSec int `toml:"max_lag_sec"` +} + +// ValidationConfig представляет конфигурацию валидации +type ValidationConfig struct { + Enabled bool `toml:"enabled"` + SamplePercent int `toml:"sample_percent"` + MaxErrors int `toml:"max_errors"` +} + +// ============================================================================= +// ВСПОМОГАТЕЛЬНЫЕ СТРУКТУРЫ +// ============================================================================= + +// ValidationResult содержит результаты валидации конфигурации. +type ValidationResult struct { + Valid bool // Корректна ли конфигурация + Errors []error // Критические ошибки + Warnings []error // Предупреждения (некритичные) +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ SagaConfig +// ============================================================================= + +// IsSagaEnabled возвращает флаг включения SAGA оркестратора. +func (s *SagaConfig) IsSagaEnabled() bool { + return s.Enabled +} + +// GetCoordinatorCount возвращает количество координаторов. +// По умолчанию 3. +func (s *SagaConfig) GetCoordinatorCount() int { + if s.CoordinatorCount < 1 { + return 3 + } + return s.CoordinatorCount +} + +// GetStateDir возвращает директорию для хранения состояний SAGA. +// По умолчанию "saga_states". +func (s *SagaConfig) GetStateDir() string { + if s.StateDir == "" { + return "saga_states" + } + return s.StateDir +} + +// GetMaxRetries возвращает максимальное количество попыток выполнения шага. +// По умолчанию 5. +func (s *SagaConfig) GetMaxRetries() int { + if s.MaxRetries <= 0 { + return 5 + } + return s.MaxRetries +} + +// GetRetryBackoff возвращает базовую задержку между повторными попытками. +// По умолчанию 100 миллисекунд. +func (s *SagaConfig) GetRetryBackoff() time.Duration { + if s.RetryBackoffMs <= 0 { + return 100 * time.Millisecond + } + return time.Duration(s.RetryBackoffMs) * time.Millisecond +} + +// GetSagaTimeout возвращает таймаут выполнения SAGA. +// По умолчанию 300 секунд (5 минут). +func (s *SagaConfig) GetSagaTimeout() time.Duration { + if s.SagaTimeoutSec <= 0 { + return 300 * time.Second + } + return time.Duration(s.SagaTimeoutSec) * time.Second +} + +// GetStuckCheckInterval возвращает интервал проверки зависших SAGA. +// По умолчанию 10 секунд. +func (s *SagaConfig) GetStuckCheckInterval() time.Duration { + if s.StuckCheckIntervalSec <= 0 { + return 10 * time.Second + } + return time.Duration(s.StuckCheckIntervalSec) * time.Second +} + +// GetLeaderElectionInterval возвращает интервал выбора лидера. +// По умолчанию 5 секунд. +func (s *SagaConfig) GetLeaderElectionInterval() time.Duration { + if s.LeaderElectionIntervalSec <= 0 { + return 5 * time.Second + } + return time.Duration(s.LeaderElectionIntervalSec) * time.Second +} + +// GetRecoveryInterval возвращает интервал восстановления незавершённых SAGA. +// По умолчанию 30 секунд. +func (s *SagaConfig) GetRecoveryInterval() time.Duration { + if s.RecoveryIntervalSec <= 0 { + return 30 * time.Second + } + return time.Duration(s.RecoveryIntervalSec) * time.Second +} + +// GetMetricsInterval возвращает интервал сбора метрик. +// По умолчанию 60 секунд. +func (s *SagaConfig) GetMetricsInterval() time.Duration { + if s.MetricsIntervalSec <= 0 { + return 60 * time.Second + } + return time.Duration(s.MetricsIntervalSec) * time.Second +} + +// GetCleanupPeriod возвращает период очистки старых SAGA. +// По умолчанию 24 часа. +func (s *SagaConfig) GetCleanupPeriod() time.Duration { + if s.CleanupPeriodHours <= 0 { + return 24 * time.Hour + } + return time.Duration(s.CleanupPeriodHours) * time.Hour +} + +// GetMaxCacheSize возвращает максимальное количество состояний в кэше. +// По умолчанию 10000. +func (s *SagaConfig) GetMaxCacheSize() int { + if s.MaxCacheSize <= 0 { + return 10000 + } + return s.MaxCacheSize +} + +// GetOperationRetentionDuration возвращает время жизни выполненных операций. +// По умолчанию 7 дней. +func (s *SagaConfig) GetOperationRetentionDuration() time.Duration { + if s.OperationRetentionDays <= 0 { + return 7 * 24 * time.Hour + } + return time.Duration(s.OperationRetentionDays) * 24 * time.Hour +} + +// GetChannelBufferSize возвращает размер буфера каналов. +// По умолчанию 10000. +func (s *SagaConfig) GetChannelBufferSize() int { + if s.ChannelBufferSize <= 0 { + return 10000 + } + return s.ChannelBufferSize +} + +// GetAsyncRecoveryWorkers возвращает количество воркеров для асинхронного восстановления. +// По умолчанию 4. +func (s *SagaConfig) GetAsyncRecoveryWorkers() int { + if s.AsyncRecoveryWorkers <= 0 { + return 4 + } + return s.AsyncRecoveryWorkers +} + +// GetAsyncRecoveryTimeout возвращает таймаут асинхронного восстановления. +// По умолчанию 30 секунд. +func (s *SagaConfig) GetAsyncRecoveryTimeout() time.Duration { + if s.AsyncRecoveryTimeoutSec <= 0 { + return 30 * time.Second + } + return time.Duration(s.AsyncRecoveryTimeoutSec) * time.Second +} + +// IsFsyncEnabled возвращает флаг принудительной синхронизации с диском. +func (s *SagaConfig) IsFsyncEnabled() bool { + return s.FsyncEnabled +} + +// GetFsyncMaxRetries возвращает количество повторных попыток синхронизации. +// По умолчанию 3. +func (s *SagaConfig) GetFsyncMaxRetries() int { + if s.FsyncMaxRetries <= 0 { + return 3 + } + return s.FsyncMaxRetries +} + +// GetFsyncRetryDelay возвращает задержку между повторными попытками синхронизации. +// По умолчанию 100 миллисекунд. +func (s *SagaConfig) GetFsyncRetryDelay() time.Duration { + if s.FsyncRetryDelayMs <= 0 { + return 100 * time.Millisecond + } + return time.Duration(s.FsyncRetryDelayMs) * time.Millisecond +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ ReplicationConfig +// ============================================================================= + +// GetReplicationTimeout возвращает таймаут репликации как time.Duration. +// Если значение не задано (≤ 0), возвращается значение по умолчанию 5 секунд. +func (r *ReplicationConfig) GetReplicationTimeout() time.Duration { + if r.ReplicationTimeoutMs <= 0 { + return 5 * time.Second + } + return time.Duration(r.ReplicationTimeoutMs) * time.Millisecond +} + +// IsReplicationEnabled возвращает флаг включения репликации. +func (r *ReplicationConfig) IsReplicationEnabled() bool { + return r.Enabled +} + +// IsSyncReplicationEnabled возвращает флаг синхронной репликации. +func (r *ReplicationConfig) IsSyncReplicationEnabled() bool { + return r.SyncReplication +} + +// GetMaxReplicaLag возвращает максимальное допустимое отставание реплики. +// Если значение не задано (≤ 0), возвращается 5 секунд. +func (r *ReplicationConfig) GetMaxReplicaLag() time.Duration { + if r.MaxReplicaLagMs <= 0 { + return 5 * time.Second + } + return time.Duration(r.MaxReplicaLagMs) * time.Millisecond +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ ClusterConfig +// ============================================================================= + +// GetHeartbeatTimeout возвращает таймаут heartbeat-сообщений. +// По умолчанию 1 секунда. +func (c *ClusterConfig) GetHeartbeatTimeout() time.Duration { + if c.HeartbeatTimeoutMs <= 0 { + return 1000 * time.Millisecond + } + return time.Duration(c.HeartbeatTimeoutMs) * time.Millisecond +} + +// GetElectionTimeout возвращает таймаут для начала выборов лидера. +// По умолчанию 1 секунда. +func (c *ClusterConfig) GetElectionTimeout() time.Duration { + if c.ElectionTimeoutMs <= 0 { + return 1000 * time.Millisecond + } + return time.Duration(c.ElectionTimeoutMs) * time.Millisecond +} + +// GetCommitTimeout возвращает таймаут коммита записей. +// По умолчанию 500 миллисекунд. +func (c *ClusterConfig) GetCommitTimeout() time.Duration { + if c.CommitTimeoutMs <= 0 { + return 500 * time.Millisecond + } + return time.Duration(c.CommitTimeoutMs) * time.Millisecond +} + +// GetSnapshotInterval возвращает интервал создания снэпшотов. +// По умолчанию 30 минут. +func (c *ClusterConfig) GetSnapshotInterval() time.Duration { + if c.SnapshotIntervalMin <= 0 { + return 30 * time.Minute + } + return time.Duration(c.SnapshotIntervalMin) * time.Minute +} + +// GetSnapshotThreshold возвращает порог количества записей для создания снэпшота. +// По умолчанию 1000 записей. +func (c *ClusterConfig) GetSnapshotThreshold() uint64 { + if c.SnapshotThreshold <= 0 { + return 1000 + } + return uint64(c.SnapshotThreshold) +} + +// IsSplitBrainPreventionEnabled возвращает флаг защиты от split-brain. +func (c *ClusterConfig) IsSplitBrainPreventionEnabled() bool { + return c.SplitBrainPrevention +} + +// GetRecoveryTimeout возвращает таймаут восстановления после сбоя. +// По умолчанию 30 секунд. +func (c *ClusterConfig) GetRecoveryTimeout() time.Duration { + if c.RecoveryTimeoutSec <= 0 { + return 30 * time.Second + } + return time.Duration(c.RecoveryTimeoutSec) * time.Second +} + +// GetRegion возвращает регион узла. +// Если не указан, возвращает "default". +func (c *ClusterConfig) GetRegion() string { + if c.Region == "" { + return "default" + } + return c.Region +} + +// GetPriorityZone возвращает приоритетную зону узла. +// Значение нормализуется в диапазон [0, 9]. +func (c *ClusterConfig) GetPriorityZone() int { + if c.PriorityZone < 0 { + return 0 + } + if c.PriorityZone > 9 { + return 9 + } + return c.PriorityZone +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ PluginsConfig +// ============================================================================= + +// GetMaxCPUTime возвращает максимальное время CPU для выполнения скрипта. +// По умолчанию 100 миллисекунд. +func (p *PluginsConfig) GetMaxCPUTime() time.Duration { + if p.MaxCPUTimeMs <= 0 { + return 100 * time.Millisecond + } + return time.Duration(p.MaxCPUTimeMs) * time.Millisecond +} + +// GetMaxMemory возвращает максимальный объем памяти для скрипта в байтах. +// По умолчанию 50 МБ. +func (p *PluginsConfig) GetMaxMemory() int64 { + if p.MaxMemoryMB <= 0 { + return 50 * 1024 * 1024 + } + return int64(p.MaxMemoryMB) * 1024 * 1024 +} + +// GetMaxExecutionTime возвращает максимальное время выполнения скрипта. +// По умолчанию 5 секунд. +func (p *PluginsConfig) GetMaxExecutionTime() time.Duration { + if p.MaxExecutionTimeSec <= 0 { + return 5 * time.Second + } + return time.Duration(p.MaxExecutionTimeSec) * time.Second +} + +// GetMaxInstructions возвращает максимальное количество инструкций для скрипта. +// По умолчанию 1 000 000. +func (p *PluginsConfig) GetMaxInstructions() int64 { + if p.MaxInstructions <= 0 { + return 1000000 + } + return p.MaxInstructions +} + +// GetHotReloadInterval возвращает интервал горячей перезагрузки скриптов. +// По умолчанию 30 секунд. +func (p *PluginsConfig) GetHotReloadInterval() time.Duration { + if p.HotReloadIntervalSec <= 0 { + return 30 * time.Second + } + return time.Duration(p.HotReloadIntervalSec) * time.Second +} + +// GetMaxEventLogSize возвращает максимальный размер лога событий. +// По умолчанию 1000 записей. +func (p *PluginsConfig) GetMaxEventLogSize() int { + if p.MaxEventLogSize <= 0 { + return 1000 + } + return p.MaxEventLogSize +} + +// GetLoadTimeout возвращает таймаут загрузки скрипта. +// По умолчанию 10 секунд. +func (p *PluginsConfig) GetLoadTimeout() time.Duration { + if p.LoadTimeoutSec <= 0 { + return 10 * time.Second + } + return time.Duration(p.LoadTimeoutSec) * time.Second +} + +// GetMaxLuaStates возвращает максимальное количество Lua-состояний. +// По умолчанию 100. +func (p *PluginsConfig) GetMaxLuaStates() int { + if p.MaxLuaStates <= 0 { + return 100 + } + return p.MaxLuaStates +} + +// GetLuaStateTTL возвращает время жизни Lua-состояния. +// По умолчанию 10 минут. +func (p *PluginsConfig) GetLuaStateTTL() time.Duration { + if p.LuaStateTTLSec <= 0 { + return 10 * time.Minute + } + return time.Duration(p.LuaStateTTLSec) * time.Second +} + +// GetEnginePluginDir возвращает директорию с плагинами движков. +// По умолчанию "engines". +func (p *PluginsConfig) GetEnginePluginDir() string { + if p.EnginePluginDir == "" { + return "engines" + } + return p.EnginePluginDir +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ WALConfig +// ============================================================================= + +// GetSegmentSize возвращает размер сегмента WAL в байтах. +// По умолчанию 64 МБ. +func (w *WALConfig) GetSegmentSize() int64 { + if w.SegmentSizeMB <= 0 { + return 64 * 1024 * 1024 + } + return int64(w.SegmentSizeMB) * 1024 * 1024 +} + +// GetSyncInterval возвращает интервал синхронизации WAL с диском. +// По умолчанию 5 секунд. +func (w *WALConfig) GetSyncInterval() time.Duration { + if w.SyncIntervalSec <= 0 { + return 5 * time.Second + } + return time.Duration(w.SyncIntervalSec) * time.Second +} + +// GetBatchSize возвращает размер пакета для записи в WAL. +// По умолчанию 100 записей. +func (w *WALConfig) GetBatchSize() int { + if w.BatchSize <= 0 { + return 100 + } + return w.BatchSize +} + +// GetRecoveryWorkers возвращает количество потоков для восстановления из WAL. +// По умолчанию 4 потока. +func (w *WALConfig) GetRecoveryWorkers() int { + if w.RecoveryWorkers <= 0 { + return 4 + } + return w.RecoveryWorkers +} + +// IsWALEnabled возвращает флаг включения WAL. +func (w *WALConfig) IsWALEnabled() bool { + return w.Enabled +} + +// IsAsyncRecoveryEnabled возвращает флаг асинхронного восстановления. +func (w *WALConfig) IsAsyncRecoveryEnabled() bool { + return w.AsyncRecovery +} + +// GetAsyncRecoveryWorkers возвращает количество потоков асинхронного восстановления. +// По умолчанию 4 потока. +func (w *WALConfig) GetAsyncRecoveryWorkers() int { + if w.AsyncRecoveryWorkers <= 0 { + return 4 + } + return w.AsyncRecoveryWorkers +} + +// GetAsyncRecoveryBuffer возвращает размер буфера асинхронного восстановления. +// По умолчанию 10 000 записей. +func (w *WALConfig) GetAsyncRecoveryBuffer() int { + if w.AsyncRecoveryBuffer <= 0 { + return 10000 + } + return w.AsyncRecoveryBuffer +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ MVCCConfig +// ============================================================================= + +// GetMaxVersionsPerDoc возвращает максимальное количество версий на документ. +// По умолчанию 10 версий. +func (m *MVCCConfig) GetMaxVersionsPerDoc() int { + if m.MaxVersionsPerDoc <= 0 { + return 10 + } + return m.MaxVersionsPerDoc +} + +// GetVisibilityMapSize возвращает размер карты видимости. +// По умолчанию 1 048 576 элементов (1 МБ). +func (m *MVCCConfig) GetVisibilityMapSize() int { + if m.VisibilityMapSize <= 0 { + return 1024 * 1024 + } + return m.VisibilityMapSize +} + +// GetPruneInterval возвращает интервал очистки старых версий. +// По умолчанию 5 минут. +func (m *MVCCConfig) GetPruneInterval() time.Duration { + if m.PruneIntervalMin <= 0 { + return 5 * time.Minute + } + return time.Duration(m.PruneIntervalMin) * time.Minute +} + +// GetRetentionDays возвращает срок хранения старых версий в днях. +// По умолчанию 7 дней. +func (m *MVCCConfig) GetRetentionDays() int { + if m.RetentionDays <= 0 { + return 7 + } + return m.RetentionDays +} + +// GetReadCacheSize возвращает размер кэша чтения. +// По умолчанию 10 000 записей. +func (m *MVCCConfig) GetReadCacheSize() int { + if m.ReadCacheSize <= 0 { + return 10000 + } + return m.ReadCacheSize +} + +// GetReadCacheTTL возвращает TTL кэша чтения. +// По умолчанию 300 секунд (5 минут). +func (m *MVCCConfig) GetReadCacheTTL() time.Duration { + if m.ReadCacheTTLSec <= 0 { + return 300 * time.Second + } + return time.Duration(m.ReadCacheTTLSec) * time.Second +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ TransactionsConfig +// ============================================================================= + +// GetDefaultTimeout возвращает таймаут транзакции по умолчанию. +// По умолчанию 30 секунд. +func (t *TransactionsConfig) GetDefaultTimeout() time.Duration { + if t.DefaultTimeoutSec <= 0 { + return 30 * time.Second + } + return time.Duration(t.DefaultTimeoutSec) * time.Second +} + +// GetDeadlockCheckInterval возвращает интервал проверки взаимоблокировок. +// По умолчанию 1 секунда. +func (t *TransactionsConfig) GetDeadlockCheckInterval() time.Duration { + if t.DeadlockCheckIntervalSec <= 0 { + return 1 * time.Second + } + return time.Duration(t.DeadlockCheckIntervalSec) * time.Second +} + +// GetMaxSavepointsPerTx возвращает максимальное количество точек сохранения. +// По умолчанию 100. +func (t *TransactionsConfig) GetMaxSavepointsPerTx() int { + if t.MaxSavepointsPerTx <= 0 { + return 100 + } + return t.MaxSavepointsPerTx +} + +// IsTransactionsEnabled возвращает флаг включения транзакций. +func (t *TransactionsConfig) IsTransactionsEnabled() bool { + return t.Enabled +} + +// GetCheckpointInterval возвращает интервал контрольных точек в секундах. +// По умолчанию 300 секунд (5 минут). +func (t *TransactionsConfig) GetCheckpointInterval() int64 { + if t.CheckpointIntervalSec <= 0 { + return 300 + } + return int64(t.CheckpointIntervalSec) +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ ACLConfig +// ============================================================================= + +// GetMaxDeniedLogSize возвращает максимальный размер лога отказов в доступе. +// По умолчанию 10 000 записей. +func (a *ACLConfig) GetMaxDeniedLogSize() int { + if a.MaxDeniedLogSize <= 0 { + return 10000 + } + return a.MaxDeniedLogSize +} + +// GetTemporaryGrantTTL возвращает TTL временных прав доступа. +// По умолчанию 24 часа. +func (a *ACLConfig) GetTemporaryGrantTTL() time.Duration { + if a.TemporaryGrantTTLHours <= 0 { + return 24 * time.Hour + } + return time.Duration(a.TemporaryGrantTTLHours) * time.Hour +} + +// IsRoleHierarchyEnabled возвращает флаг включения иерархии ролей. +func (a *ACLConfig) IsRoleHierarchyEnabled() bool { + return a.EnableRoleHierarchy +} + +// GetCacheTTL возвращает TTL кэша ACL. +// По умолчанию 60 секунд. +func (a *ACLConfig) GetCacheTTL() time.Duration { + if a.CacheTTLSec <= 0 { + return 60 * time.Second + } + return time.Duration(a.CacheTTLSec) * time.Second +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ TLSConfig +// ============================================================================= + +// GetTLSMinVersion возвращает минимальную версию TLS как строку. +// По умолчанию "1.2". +func (t *TLSConfig) GetTLSMinVersion() string { + if t.MinVersion == "" { + return "1.2" + } + return t.MinVersion +} + +// IsTLSEnabled возвращает флаг включения TLS. +func (t *TLSConfig) IsTLSEnabled() bool { + return t.Enabled +} + +// IsMutualAuthEnabled возвращает флаг взаимной аутентификации. +func (t *TLSConfig) IsMutualAuthEnabled() bool { + return t.MutualAuth +} + +// GetKeyRotationDays возвращает интервал ротации ключей в днях. +// По умолчанию 30 дней. +func (t *TLSConfig) GetKeyRotationDays() int { + if t.KeyRotationDays <= 0 { + return 30 + } + return t.KeyRotationDays +} + +// IsAutoGenerateEnabled возвращает флаг автоматической генерации сертификатов. +func (t *TLSConfig) IsAutoGenerateEnabled() bool { + return t.AutoGenerate +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ BackpressureConfig +// ============================================================================= + +// IsBackpressureEnabled возвращает флаг включения механизма обратного давления. +func (b *BackpressureConfig) IsBackpressureEnabled() bool { + return b.Enabled +} + +// GetCPUThreshold возвращает порог загрузки CPU. +// По умолчанию 0.8 (80%). +// Значение нормализуется в диапазон [0, 1]. +func (b *BackpressureConfig) GetCPUThreshold() float64 { + if b.CPUThreshold <= 0 { + return 0.8 + } + if b.CPUThreshold > 1.0 { + return 1.0 + } + return b.CPUThreshold +} + +// GetMemoryThreshold возвращает порог использования памяти. +// По умолчанию 0.85 (85%). +// Значение нормализуется в диапазон [0, 1]. +func (b *BackpressureConfig) GetMemoryThreshold() float64 { + if b.MemoryThreshold <= 0 { + return 0.85 + } + if b.MemoryThreshold > 1.0 { + return 1.0 + } + return b.MemoryThreshold +} + +// GetQueueSizeThreshold возвращает порог размера очереди. +// По умолчанию 10 000 записей. +func (b *BackpressureConfig) GetQueueSizeThreshold() int { + if b.QueueSizeThreshold <= 0 { + return 10000 + } + return b.QueueSizeThreshold +} + +// GetConnectionThreshold возвращает порог количества соединений. +// По умолчанию 5 000. +func (b *BackpressureConfig) GetConnectionThreshold() int { + if b.ConnectionThreshold <= 0 { + return 5000 + } + return b.ConnectionThreshold +} + +// GetCheckInterval возвращает интервал проверки нагрузки. +// По умолчанию 1 секунда. +func (b *BackpressureConfig) GetCheckInterval() time.Duration { + if b.CheckIntervalMs <= 0 { + return 1 * time.Second + } + return time.Duration(b.CheckIntervalMs) * time.Millisecond +} + +// GetLowDelay возвращает задержку при низкой нагрузке. +// По умолчанию 100 миллисекунд. +func (b *BackpressureConfig) GetLowDelay() time.Duration { + if b.LowDelayMs <= 0 { + return 100 * time.Millisecond + } + return time.Duration(b.LowDelayMs) * time.Millisecond +} + +// GetMediumRejectProb возвращает вероятность отказа при средней нагрузке. +// Значение нормализуется в диапазон [0, 100]. +func (b *BackpressureConfig) GetMediumRejectProb() uint32 { + if b.MediumRejectProb > 100 { + return 100 + } + return b.MediumRejectProb +} + +// GetHighRejectProb возвращает вероятность отказа при высокой нагрузке. +// Значение нормализуется в диапазон [0, 100]. +func (b *BackpressureConfig) GetHighRejectProb() uint32 { + if b.HighRejectProb > 100 { + return 100 + } + return b.HighRejectProb +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ RuntimeLimitsConfig +// ============================================================================= + +// IsRuntimeLimitsEnabled возвращает флаг включения ограничений времени выполнения. +func (r *RuntimeLimitsConfig) IsRuntimeLimitsEnabled() bool { + return r.Enabled +} + +// GetGlobalMaxDocSizeMB возвращает максимальный размер документа в МБ. +// По умолчанию 16 МБ. +func (r *RuntimeLimitsConfig) GetGlobalMaxDocSizeMB() int { + if r.GlobalMaxDocSizeMB <= 0 { + return 16 + } + return r.GlobalMaxDocSizeMB +} + +// GetGlobalMaxCollSizeMB возвращает максимальный размер коллекции в МБ. +// По умолчанию 10240 МБ (10 ГБ). +func (r *RuntimeLimitsConfig) GetGlobalMaxCollSizeMB() int64 { + if r.GlobalMaxCollSizeMB <= 0 { + return 10240 + } + return r.GlobalMaxCollSizeMB +} + +// GetGlobalMaxDocsPerColl возвращает максимальное количество документов в коллекции. +// По умолчанию 10 000 000. +func (r *RuntimeLimitsConfig) GetGlobalMaxDocsPerColl() int64 { + if r.GlobalMaxDocsPerColl <= 0 { + return 10000000 + } + return r.GlobalMaxDocsPerColl +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ AutoscalingConfig +// ============================================================================= + +// IsAutoscalingEnabled возвращает флаг включения автомасштабирования. +func (a *AutoscalingConfig) IsAutoscalingEnabled() bool { + return a.Enabled +} + +// GetMinNodes возвращает минимальное количество узлов. +// По умолчанию 1. +func (a *AutoscalingConfig) GetMinNodes() int { + if a.MinNodes <= 0 { + return 1 + } + return a.MinNodes +} + +// GetMaxNodes возвращает максимальное количество узлов. +// По умолчанию 10. +func (a *AutoscalingConfig) GetMaxNodes() int { + if a.MaxNodes <= 0 { + return 10 + } + return a.MaxNodes +} + +// GetScaleUpThreshold возвращает порог для масштабирования вверх. +// По умолчанию 0.75 (75%). +// Значение нормализуется в диапазон [0, 1]. +func (a *AutoscalingConfig) GetScaleUpThreshold() float64 { + if a.ScaleUpThreshold <= 0 { + return 0.75 + } + if a.ScaleUpThreshold > 1.0 { + return 1.0 + } + return a.ScaleUpThreshold +} + +// GetScaleDownThreshold возвращает порог для масштабирования вниз. +// По умолчанию 0.30 (30%). +func (a *AutoscalingConfig) GetScaleDownThreshold() float64 { + if a.ScaleDownThreshold <= 0 { + return 0.30 + } + return a.ScaleDownThreshold +} + +// GetScaleUpCooldown возвращает задержку перед масштабированием вверх. +// По умолчанию 5 минут. +func (a *AutoscalingConfig) GetScaleUpCooldown() time.Duration { + if a.ScaleUpCooldownSec <= 0 { + return 5 * time.Minute + } + return time.Duration(a.ScaleUpCooldownSec) * time.Second +} + +// GetScaleDownCooldown возвращает задержку перед масштабированием вниз. +// По умолчанию 10 минут. +func (a *AutoscalingConfig) GetScaleDownCooldown() time.Duration { + if a.ScaleDownCooldownSec <= 0 { + return 10 * time.Minute + } + return time.Duration(a.ScaleDownCooldownSec) * time.Second +} + +// GetEvaluationInterval возвращает интервал оценки нагрузки. +// По умолчанию 30 секунд. +func (a *AutoscalingConfig) GetEvaluationInterval() time.Duration { + if a.EvaluationIntervalSec <= 0 { + return 30 * time.Second + } + return time.Duration(a.EvaluationIntervalSec) * time.Second +} + +// IsPredictiveEnabled возвращает флаг прогнозирующего масштабирования. +func (a *AutoscalingConfig) IsPredictiveEnabled() bool { + return a.PredictiveEnabled +} + +// GetMaxScaleUpNodes возвращает максимальное количество узлов для масштабирования вверх. +// По умолчанию 3. +func (a *AutoscalingConfig) GetMaxScaleUpNodes() int { + if a.MaxScaleUpNodes <= 0 { + return 3 + } + return a.MaxScaleUpNodes +} + +// GetMaxScaleDownNodes возвращает максимальное количество узлов для масштабирования вниз. +// По умолчанию 2. +func (a *AutoscalingConfig) GetMaxScaleDownNodes() int { + if a.MaxScaleDownNodes <= 0 { + return 2 + } + return a.MaxScaleDownNodes +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ SchemaMigrationConfig +// ============================================================================= + +// IsSchemaMigrationEnabled возвращает флаг включения миграции схемы. +func (s *SchemaMigrationConfig) IsSchemaMigrationEnabled() bool { + return s.Enabled +} + +// GetMigrationDir возвращает директорию с миграциями. +// По умолчанию "migrations". +func (s *SchemaMigrationConfig) GetMigrationDir() string { + if s.MigrationDir == "" { + return "migrations" + } + return s.MigrationDir +} + +// IsAutoMigrateEnabled возвращает флаг автоматической миграции при старте. +func (s *SchemaMigrationConfig) IsAutoMigrateEnabled() bool { + return s.AutoMigrate +} + +// GetTargetVersion возвращает целевую версию схемы. +// По умолчанию "latest". +func (s *SchemaMigrationConfig) GetTargetVersion() string { + if s.TargetVersion == "" { + return "latest" + } + return s.TargetVersion +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ BackupConfig +// ============================================================================= + +// IsBackupEnabled возвращает флаг включения резервного копирования. +func (b *BackupConfig) IsBackupEnabled() bool { + return b.Enabled +} + +// GetBackupDir возвращает директорию для резервных копий. +// По умолчанию "backups". +func (b *BackupConfig) GetBackupDir() string { + if b.BackupDir == "" { + return "backups" + } + return b.BackupDir +} + +// GetMaxConcurrentBackups возвращает максимальное количество параллельных бэкапов. +// По умолчанию 1. +func (b *BackupConfig) GetMaxConcurrentBackups() int { + if b.MaxConcurrent <= 0 { + return 1 + } + return b.MaxConcurrent +} + +// IsCompressEnabled возвращает флаг сжатия резервных копий. +func (b *BackupConfig) IsCompressEnabled() bool { + return b.CompressEnabled +} + +// GetBackupRetentionDays возвращает срок хранения резервных копий в днях. +// По умолчанию 7 дней. +func (b *BackupConfig) GetBackupRetentionDays() int { + if b.RetentionDays <= 0 { + return 7 + } + return b.RetentionDays +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ StorageConfig +// ============================================================================= + +// GetDefaultEngine возвращает движок хранения по умолчанию. +// По умолчанию "row". +func (s *StorageConfig) GetDefaultEngine() string { + if s.DefaultEngine == "" { + return "row" + } + return s.DefaultEngine +} + +// IsCustomEnginesEnabled возвращает флаг включения пользовательских движков. +func (s *StorageConfig) IsCustomEnginesEnabled() bool { + return s.EnableCustomEngines +} + +// ============================================================================= +// МЕТОДЫ ДЛЯ EnginesConfig +// ============================================================================= + +// IsEngineEnabled проверяет, включен ли указанный движок хранения. +// Поддерживаются: row, columnar, document, kv, ts, graph. +func (e *EnginesConfig) IsEngineEnabled(name string) bool { + switch name { + case "row": + return e.Row.Enabled + case "columnar": + return e.Columnar.Enabled + case "document": + return e.Document.Enabled + case "kv": + return e.KV.Enabled + case "ts": + return e.TS.Enabled + case "graph": + return e.Graph.Enabled + default: + return false + } +} + +// GetEngineConfig возвращает конфигурацию указанного движка хранения. +// Возвращает пустую карту, если движок не найден. +func (e *EnginesConfig) GetEngineConfig(name string) map[string]interface{} { + switch name { + case "row": + return e.Row.Config + case "columnar": + return e.Columnar.Config + case "document": + return e.Document.Config + case "kv": + return e.KV.Config + case "ts": + return e.TS.Config + case "graph": + return e.Graph.Config + default: + return make(map[string]interface{}) + } +} + +// GetEngineDescription возвращает описание указанного движка хранения. +// Возвращает пустую строку, если движок не найден. +func (e *EnginesConfig) GetEngineDescription(name string) string { + switch name { + case "row": + return e.Row.Description + case "columnar": + return e.Columnar.Description + case "document": + return e.Document.Description + case "kv": + return e.KV.Description + case "ts": + return e.TS.Description + case "graph": + return e.Graph.Description + default: + return "" + } +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ RecoveryConfig +// ============================================================================= + +// GetMaxRetryDuration возвращает максимальную длительность повторных попыток. +// По умолчанию 300 секунд (5 минут). +func (r *RecoveryConfig) GetMaxRetryDuration() time.Duration { + if r.MaxRetrySec <= 0 { + return 300 * time.Second + } + return time.Duration(r.MaxRetrySec) * time.Second +} + +// GetDataReplicationTimeout возвращает таймаут репликации данных при восстановлении. +// По умолчанию 60 секунд. +func (r *RecoveryConfig) GetDataReplicationTimeout() time.Duration { + if r.DataReplicationTimeoutSec <= 0 { + return 60 * time.Second + } + return time.Duration(r.DataReplicationTimeoutSec) * time.Second +} + +// GetStaleReadTimeout возвращает таймаут для чтения устаревших данных. +// По умолчанию 30 секунд. +func (r *RecoveryConfig) GetStaleReadTimeout() time.Duration { + if r.StaleReadTimeoutSec <= 0 { + return 30 * time.Second + } + return time.Duration(r.StaleReadTimeoutSec) * time.Second +} + +// IsAutoRejoinEnabled возвращает флаг автоматического переподключения. +func (r *RecoveryConfig) IsAutoRejoinEnabled() bool { + return r.AutoRejoin +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ PerformanceConfig +// ============================================================================= + +// GetBatchSize возвращает размер пакета для пакетных операций. +// По умолчанию 100 записей. +func (p *PerformanceConfig) GetBatchSize() int { + if p.BatchSize <= 0 { + return 100 + } + return p.BatchSize +} + +// GetMaxConnections возвращает максимальное количество соединений. +// По умолчанию 1000. +func (p *PerformanceConfig) GetMaxConnections() int { + if p.MaxConnections <= 0 { + return 1000 + } + return p.MaxConnections +} + +// IsReadFromFollowerEnabled возвращает флаг чтения с ведомых узлов. +func (p *PerformanceConfig) IsReadFromFollowerEnabled() bool { + return p.ReadFromFollower +} + +// IsPipelineEnabled возвращает флаг конвейерной обработки. +func (p *PerformanceConfig) IsPipelineEnabled() bool { + return p.EnablePipeline +} + +// GetReadReplicaDelay возвращает задержку чтения с реплики. +// По умолчанию 100 миллисекунд. +func (p *PerformanceConfig) GetReadReplicaDelay() time.Duration { + if p.ReadReplicaDelayMs <= 0 { + return 100 * time.Millisecond + } + return time.Duration(p.ReadReplicaDelayMs) * time.Millisecond +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ MonitoringConfig +// ============================================================================= + +// GetMetricsPort возвращает порт для экспорта метрик. +// По умолчанию 9090. +func (m *MonitoringConfig) GetMetricsPort() int { + if m.MetricsPort <= 0 { + return 9090 + } + return m.MetricsPort +} + +// GetTraceSampleRate возвращает частоту сэмплирования трассировки. +// Нормализуется в диапазон (0, 1]. +func (m *MonitoringConfig) GetTraceSampleRate() float64 { + if m.TraceSampleRate <= 0 || m.TraceSampleRate > 1 { + return 0.01 + } + return m.TraceSampleRate +} + +// IsMetricsEnabled возвращает флаг включения сбора метрик. +func (m *MonitoringConfig) IsMetricsEnabled() bool { + return m.EnableMetrics +} + +// IsTracingEnabled возвращает флаг включения трассировки. +func (m *MonitoringConfig) IsTracingEnabled() bool { + return m.EnableTracing +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ SecurityConfig +// ============================================================================= + +// GetTLSMinVersion возвращает минимальную версию TLS как числовой код. +// Используется для настройки TLS-соединений. +// Возвращает 0x0303 (TLS 1.2) по умолчанию. +func (s *SecurityConfig) GetTLSMinVersion() uint16 { + switch s.MinVersion { + case "1.0": + return 0x0301 + case "1.1": + return 0x0302 + case "1.2": + return 0x0303 + case "1.3": + return 0x0304 + default: + return 0x0303 + } +} + +// IsTLSEnabled возвращает флаг включения TLS. +// TLS считается включенным, если EnableTLS=true и указаны файлы сертификата и ключа. +func (s *SecurityConfig) IsTLSEnabled() bool { + return s.EnableTLS && s.CertFile != "" && s.KeyFile != "" +} + +// GetCertFile возвращает путь к файлу сертификата. +func (s *SecurityConfig) GetCertFile() string { + return s.CertFile +} + +// GetKeyFile возвращает путь к файлу приватного ключа. +func (s *SecurityConfig) GetKeyFile() string { + return s.KeyFile +} + +// GetCAFile возвращает путь к файлу корневого сертификата CA. +func (s *SecurityConfig) GetCAFile() string { + return s.CAFile +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ CompressionConfig +// ============================================================================= + +// IsCompressionEnabled возвращает флаг включения сжатия. +func (c *CompressionConfig) IsCompressionEnabled() bool { + return c.Enabled +} + +// GetAlgorithm возвращает алгоритм сжатия. +// По умолчанию "snappy". +func (c *CompressionConfig) GetAlgorithm() string { + if c.Algorithm == "" { + return "snappy" + } + return c.Algorithm +} + +// GetLevel возвращает уровень сжатия. +// Нормализуется в диапазон [1, 9]. +func (c *CompressionConfig) GetLevel() int { + if c.Level < 1 { + return 3 + } + if c.Level > 9 { + return 9 + } + return c.Level +} + +// GetMinSize возвращает минимальный размер данных для сжатия в байтах. +// По умолчанию 1024 байта. +func (c *CompressionConfig) GetMinSize() int { + if c.MinSize <= 0 { + return 1024 + } + return c.MinSize +} + +// ============================================================================= +// ГЕТТЕРЫ ДЛЯ WebUIConfig +// ============================================================================= + +// IsWebUIEnabled возвращает флаг включения веб-интерфейса. +func (w *WebUIConfig) IsWebUIEnabled() bool { + return w.Enabled +} + +// GetWebUIPort возвращает порт для веб-интерфейса. +// По умолчанию 8080. +func (w *WebUIConfig) GetWebUIPort() int { + if w.Port <= 0 { + return 8080 + } + return w.Port +} + +// GetTheme возвращает тему веб-интерфейса. +// По умолчанию "dark". +func (w *WebUIConfig) GetTheme() string { + if w.Theme == "" { + return "dark" + } + return w.Theme +} + +// ============================================================================= +// ЗАГРУЗКА И ВАЛИДАЦИЯ КОНФИГУРАЦИИ +// ============================================================================= + +// LoadConfig загружает и валидирует конфигурацию из TOML-файла. +// +// Алгоритм работы: +// 1. Декодирование TOML-файла в структуру Config +// 2. Применение значений по умолчанию для всех параметров +// 3. Полная валидация конфигурации +// 4. Вывод предупреждений (если есть) +// 5. Возврат заполненной структуры или ошибки +// +// Параметры: +// - path: путь к TOML-файлу конфигурации +// +// Возвращает: +// - *Config: заполненная структура конфигурации +// - error: ошибка загрузки или валидации +func LoadConfig(path string) (*Config, error) { + var cfg Config + if _, err := toml.DecodeFile(path, &cfg); err != nil { + return nil, fmt.Errorf("failed to decode config file: %v", err) + } + + // ===== УСТАНОВКА ЗНАЧЕНИЙ ПО УМОЛЧАНИЮ ===== + // Все значения по умолчанию гарантируют работоспособность + // даже при отсутствии соответствующих секций в конфиге. + + // Кластерные настройки + if cfg.Cluster.RaftPort == 0 { + cfg.Cluster.RaftPort = 9878 // Порт Raft по умолчанию + } + if cfg.Cluster.RaftDataDir == "" { + cfg.Cluster.RaftDataDir = "raft_data" // Директория Raft-лога + } + if cfg.Cluster.HeartbeatTimeoutMs == 0 { + cfg.Cluster.HeartbeatTimeoutMs = 1000 // 1 секунда + } + if cfg.Cluster.ElectionTimeoutMs == 0 { + cfg.Cluster.ElectionTimeoutMs = 1000 // 1 секунда + } + if cfg.Cluster.CommitTimeoutMs == 0 { + cfg.Cluster.CommitTimeoutMs = 500 // 500 мс + } + if cfg.Cluster.SnapshotIntervalMin == 0 { + cfg.Cluster.SnapshotIntervalMin = 30 // 30 минут + } + if cfg.Cluster.SnapshotThreshold == 0 { + cfg.Cluster.SnapshotThreshold = 1000 // 1000 записей + } + if cfg.Cluster.RecoveryTimeoutSec == 0 { + cfg.Cluster.RecoveryTimeoutSec = 30 // 30 секунд + } + if cfg.Cluster.Region == "" { + cfg.Cluster.Region = "default" // Регион по умолчанию + } + + // Настройки SAGA + if cfg.Saga.CoordinatorCount == 0 { + cfg.Saga.CoordinatorCount = 3 + } + if cfg.Saga.StateDir == "" { + cfg.Saga.StateDir = "saga_states" + } + if cfg.Saga.MaxRetries == 0 { + cfg.Saga.MaxRetries = 5 + } + if cfg.Saga.RetryBackoffMs == 0 { + cfg.Saga.RetryBackoffMs = 100 + } + if cfg.Saga.SagaTimeoutSec == 0 { + cfg.Saga.SagaTimeoutSec = 300 + } + if cfg.Saga.StuckCheckIntervalSec == 0 { + cfg.Saga.StuckCheckIntervalSec = 10 + } + if cfg.Saga.LeaderElectionIntervalSec == 0 { + cfg.Saga.LeaderElectionIntervalSec = 5 + } + if cfg.Saga.RecoveryIntervalSec == 0 { + cfg.Saga.RecoveryIntervalSec = 30 + } + if cfg.Saga.MetricsIntervalSec == 0 { + cfg.Saga.MetricsIntervalSec = 60 + } + if cfg.Saga.CleanupPeriodHours == 0 { + cfg.Saga.CleanupPeriodHours = 24 + } + if cfg.Saga.MaxCacheSize == 0 { + cfg.Saga.MaxCacheSize = 10000 + } + if cfg.Saga.OperationRetentionDays == 0 { + cfg.Saga.OperationRetentionDays = 7 + } + if cfg.Saga.ChannelBufferSize == 0 { + cfg.Saga.ChannelBufferSize = 10000 + } + if cfg.Saga.AsyncRecoveryWorkers == 0 { + cfg.Saga.AsyncRecoveryWorkers = 4 + } + if cfg.Saga.AsyncRecoveryTimeoutSec == 0 { + cfg.Saga.AsyncRecoveryTimeoutSec = 30 + } + if cfg.Saga.FsyncMaxRetries == 0 { + cfg.Saga.FsyncMaxRetries = 3 + } + if cfg.Saga.FsyncRetryDelayMs == 0 { + cfg.Saga.FsyncRetryDelayMs = 100 + } + + // Настройки репликации + if cfg.Replication.ReplicationTimeoutMs == 0 { + cfg.Replication.ReplicationTimeoutMs = 5000 // 5 секунд + } + if cfg.Replication.MaxReplicaLagMs == 0 { + cfg.Replication.MaxReplicaLagMs = 5000 // 5 секунд + } + + // Настройки плагинов + if cfg.Plugins.ScriptDir == "" { + cfg.Plugins.ScriptDir = "plugins" // Директория плагинов + } + if cfg.Plugins.EnginePluginDir == "" { + cfg.Plugins.EnginePluginDir = "engines" // Директория движков + } + if cfg.Plugins.MaxCPUTimeMs == 0 { + cfg.Plugins.MaxCPUTimeMs = 100 // 100 мс + } + if cfg.Plugins.MaxMemoryMB == 0 { + cfg.Plugins.MaxMemoryMB = 50 // 50 МБ + } + if cfg.Plugins.MaxExecutionTimeSec == 0 { + cfg.Plugins.MaxExecutionTimeSec = 5 // 5 секунд + } + if cfg.Plugins.MaxInstructions == 0 { + cfg.Plugins.MaxInstructions = 1000000 // 1 млн инструкций + } + if cfg.Plugins.HotReloadIntervalSec == 0 { + cfg.Plugins.HotReloadIntervalSec = 30 // 30 секунд + } + if cfg.Plugins.MaxEventLogSize == 0 { + cfg.Plugins.MaxEventLogSize = 1000 // 1000 записей + } + if cfg.Plugins.LoadTimeoutSec == 0 { + cfg.Plugins.LoadTimeoutSec = 10 // 10 секунд + } + if cfg.Plugins.MaxLuaStates == 0 { + cfg.Plugins.MaxLuaStates = 100 // 100 состояний + } + if cfg.Plugins.LuaStateTTLSec == 0 { + cfg.Plugins.LuaStateTTLSec = 600 // 10 минут + } + + // Настройки API + if cfg.API.Port == 0 { + cfg.API.Port = 8080 // Порт API по умолчанию + } + + // Настройки сжатия + if cfg.Compression.Algorithm == "" { + cfg.Compression.Algorithm = "snappy" + } + if cfg.Compression.MinSize == 0 { + cfg.Compression.MinSize = 1024 // 1 КБ + } + if cfg.Compression.Level == 0 { + cfg.Compression.Level = 3 // Уровень сжатия по умолчанию + } + + // Настройки веб-интерфейса + if cfg.WebUI.Port == 0 { + cfg.WebUI.Port = 9080 // Порт WebUI по умолчанию + } + if cfg.WebUI.Theme == "" { + cfg.WebUI.Theme = "dark" + } + + // Настройки производительности + if cfg.Performance.BatchSize == 0 { + cfg.Performance.BatchSize = 100 + } + if cfg.Performance.MaxConnections == 0 { + cfg.Performance.MaxConnections = 1000 + } + if cfg.Performance.ReadReplicaDelayMs == 0 { + cfg.Performance.ReadReplicaDelayMs = 100 // 100 мс + } + + // Настройки мониторинга + if cfg.Monitoring.MetricsPort == 0 { + cfg.Monitoring.MetricsPort = 9090 + } + if cfg.Monitoring.TraceSampleRate == 0 { + cfg.Monitoring.TraceSampleRate = 0.01 // 1% + } + + // Настройки восстановления + if cfg.Recovery.MaxRetrySec == 0 { + cfg.Recovery.MaxRetrySec = 300 // 5 минут + } + if cfg.Recovery.DataReplicationTimeoutSec == 0 { + cfg.Recovery.DataReplicationTimeoutSec = 60 // 1 минута + } + if cfg.Recovery.StaleReadTimeoutSec == 0 { + cfg.Recovery.StaleReadTimeoutSec = 30 // 30 секунд + } + + // Настройки безопасности + if cfg.Security.MinVersion == "" { + cfg.Security.MinVersion = "1.2" // TLS 1.2 + } + + // Настройки хранилища + if cfg.Storage.DefaultEngine == "" { + cfg.Storage.DefaultEngine = "row" // Строчный движок по умолчанию + } + + // Настройки WAL + if cfg.WAL.SegmentSizeMB == 0 { + cfg.WAL.SegmentSizeMB = 64 // 64 МБ + } + if cfg.WAL.SyncIntervalSec == 0 { + cfg.WAL.SyncIntervalSec = 5 // 5 секунд + } + if cfg.WAL.BatchSize == 0 { + cfg.WAL.BatchSize = 100 + } + if cfg.WAL.RecoveryWorkers == 0 { + cfg.WAL.RecoveryWorkers = 4 + } + if cfg.WAL.AsyncRecoveryWorkers == 0 { + cfg.WAL.AsyncRecoveryWorkers = 4 + } + if cfg.WAL.AsyncRecoveryBuffer == 0 { + cfg.WAL.AsyncRecoveryBuffer = 10000 + } + + // Настройки MVCC + if cfg.MVCC.MaxVersionsPerDoc == 0 { + cfg.MVCC.MaxVersionsPerDoc = 10 + } + if cfg.MVCC.VisibilityMapSize == 0 { + cfg.MVCC.VisibilityMapSize = 1024 * 1024 + } + if cfg.MVCC.PruneIntervalMin == 0 { + cfg.MVCC.PruneIntervalMin = 5 // 5 минут + } + if cfg.MVCC.RetentionDays == 0 { + cfg.MVCC.RetentionDays = 7 // 7 дней + } + if cfg.MVCC.ReadCacheSize == 0 { + cfg.MVCC.ReadCacheSize = 10000 + } + if cfg.MVCC.ReadCacheTTLSec == 0 { + cfg.MVCC.ReadCacheTTLSec = 300 // 5 минут + } + + // Настройки транзакций + if cfg.Transactions.DefaultTimeoutSec == 0 { + cfg.Transactions.DefaultTimeoutSec = 30 // 30 секунд + } + if cfg.Transactions.DeadlockCheckIntervalSec == 0 { + cfg.Transactions.DeadlockCheckIntervalSec = 1 // 1 секунда + } + if cfg.Transactions.MaxSavepointsPerTx == 0 { + cfg.Transactions.MaxSavepointsPerTx = 100 + } + if cfg.Transactions.CheckpointIntervalSec == 0 { + cfg.Transactions.CheckpointIntervalSec = 300 // 5 минут + } + + // Настройки ACL + if cfg.ACL.MaxDeniedLogSize == 0 { + cfg.ACL.MaxDeniedLogSize = 10000 + } + if cfg.ACL.TemporaryGrantTTLHours == 0 { + cfg.ACL.TemporaryGrantTTLHours = 24 // 24 часа + } + if cfg.ACL.CacheTTLSec == 0 { + cfg.ACL.CacheTTLSec = 60 // 60 секунд + } + + // Настройки кластерного TLS + if cfg.ClusterTLS.MinVersion == "" { + cfg.ClusterTLS.MinVersion = "1.2" + } + if cfg.ClusterTLS.KeyRotationDays == 0 { + cfg.ClusterTLS.KeyRotationDays = 30 // 30 дней + } + + // Настройки обратного давления + if cfg.Backpressure.CheckIntervalMs == 0 { + cfg.Backpressure.CheckIntervalMs = 1000 // 1 секунда + } + if cfg.Backpressure.LowDelayMs == 0 { + cfg.Backpressure.LowDelayMs = 100 // 100 мс + } + + // Настройки ограничений времени выполнения + if cfg.RuntimeLimits.GlobalMaxDocSizeMB == 0 { + cfg.RuntimeLimits.GlobalMaxDocSizeMB = 16 // 16 МБ + } + if cfg.RuntimeLimits.GlobalMaxCollSizeMB == 0 { + cfg.RuntimeLimits.GlobalMaxCollSizeMB = 10240 // 10 ГБ + } + if cfg.RuntimeLimits.GlobalMaxDocsPerColl == 0 { + cfg.RuntimeLimits.GlobalMaxDocsPerColl = 10000000 // 10 млн + } + + // Настройки автомасштабирования + if cfg.Autoscaling.MinNodes == 0 { + cfg.Autoscaling.MinNodes = 1 + } + if cfg.Autoscaling.MaxNodes == 0 { + cfg.Autoscaling.MaxNodes = 10 + } + if cfg.Autoscaling.ScaleUpCooldownSec == 0 { + cfg.Autoscaling.ScaleUpCooldownSec = 300 // 5 минут + } + if cfg.Autoscaling.ScaleDownCooldownSec == 0 { + cfg.Autoscaling.ScaleDownCooldownSec = 600 // 10 минут + } + if cfg.Autoscaling.EvaluationIntervalSec == 0 { + cfg.Autoscaling.EvaluationIntervalSec = 30 // 30 секунд + } + + // Настройки миграции схемы + if cfg.SchemaMigration.MigrationDir == "" { + cfg.SchemaMigration.MigrationDir = "migrations" + } + + // Настройки резервного копирования + if cfg.Backup.BackupDir == "" { + cfg.Backup.BackupDir = "backups" + } + if cfg.Backup.RetentionDays == 0 { + cfg.Backup.RetentionDays = 7 // 7 дней + } + + // Настройки кросс-датацентровой миграции + if cfg.Migration.Source == nil { + cfg.Migration.Source = &DatacenterConfig{ + Name: "dc-primary", + Endpoint: "localhost:8080", + TimeoutSec: 30, + } + } + if cfg.Migration.Target == nil { + cfg.Migration.Target = &DatacenterConfig{ + Name: "dc-secondary", + Endpoint: "localhost:8081", + TimeoutSec: 30, + } + } + if cfg.Migration.Settings == nil { + cfg.Migration.Settings = &MigrationSettings{ + BatchSize: 1000, + Workers: 4, + Compression: "snappy", + ResumeEnabled: true, + CheckpointIntervalSec: 30, + MaxRetries: 3, + RetryBackoffSec: 5, + } + } + if cfg.Migration.Delta == nil { + cfg.Migration.Delta = &DeltaSyncConfig{ + Enabled: true, + IntervalSec: 60, + MaxLagSec: 300, + } + } + if cfg.Migration.Validation == nil { + cfg.Migration.Validation = &ValidationConfig{ + Enabled: true, + SamplePercent: 10, + MaxErrors: 100, + } + } + if cfg.Migration.Mode == "" { + cfg.Migration.Mode = "semi_auto" + } + + // ===== ИНИЦИАЛИЗАЦИЯ ДВИЖКОВ ===== + // Строчный движок включен по умолчанию + if !cfg.Engines.Row.Enabled { + cfg.Engines.Row.Enabled = true + cfg.Engines.Row.Description = "Row-based storage engine (default)" + } + // Инициализация конфигураций движков + if cfg.Engines.Row.Config == nil { + cfg.Engines.Row.Config = make(map[string]interface{}) + } + if cfg.Engines.Columnar.Config == nil { + cfg.Engines.Columnar.Config = make(map[string]interface{}) + } + if cfg.Engines.Document.Config == nil { + cfg.Engines.Document.Config = make(map[string]interface{}) + } + if cfg.Engines.KV.Config == nil { + cfg.Engines.KV.Config = make(map[string]interface{}) + } + if cfg.Engines.TS.Config == nil { + cfg.Engines.TS.Config = make(map[string]interface{}) + } + if cfg.Engines.Graph.Config == nil { + cfg.Engines.Graph.Config = make(map[string]interface{}) + } + + // ===== ВАЛИДАЦИЯ КОНФИГУРАЦИИ ===== + validationResult := ValidateConfigFull(&cfg) + if !validationResult.Valid { + var errMsg strings.Builder + errMsg.WriteString("config validation failed:\n") + for _, err := range validationResult.Errors { + errMsg.WriteString(fmt.Sprintf(" - %s\n", err.Error())) + } + if len(validationResult.Warnings) > 0 { + errMsg.WriteString("Warnings:\n") + for _, warn := range validationResult.Warnings { + errMsg.WriteString(fmt.Sprintf(" - %s\n", warn.Error())) + } + } + return nil, fmt.Errorf("%s", errMsg.String()) + } + + // Вывод предупреждений (если они есть) + if len(validationResult.Warnings) > 0 { + fmt.Println("Configuration warnings:") + for _, warn := range validationResult.Warnings { + fmt.Printf(" - %s\n", warn.Error()) + } + } + + return &cfg, nil +} + +// ValidateConfigFull выполняет полную валидацию конфигурации. +// +// Проверяются: +// - Корректность портов (диапазон 1-65535) +// - Отсутствие конфликтов портов между службами +// - Корректность параметров (диапазоны, зависимости) +// - Совместимость настроек +// +// Возвращает ValidationResult с ошибками и предупреждениями. +func ValidateConfigFull(cfg *Config) *ValidationResult { + result := &ValidationResult{ + Valid: true, + Errors: make([]error, 0), + Warnings: make([]error, 0), + } + + // ===== ВАЛИДАЦИЯ КЛАСТЕРНОЙ КОНФИГУРАЦИИ ===== + if cfg.Cluster.NodePort <= 0 || cfg.Cluster.NodePort > 65535 { + result.Errors = append(result.Errors, fmt.Errorf("invalid node_port: %d (must be 1-65535)", cfg.Cluster.NodePort)) + } + if cfg.Cluster.RaftPort <= 0 || cfg.Cluster.RaftPort > 65535 { + result.Errors = append(result.Errors, fmt.Errorf("invalid raft_port: %d (must be 1-65535)", cfg.Cluster.RaftPort)) + } + if cfg.Cluster.PriorityZone < 0 || cfg.Cluster.PriorityZone > 9 { + result.Errors = append(result.Errors, fmt.Errorf("priority_zone must be between 0 and 9, got %d", cfg.Cluster.PriorityZone)) + } + + // ===== ВАЛИДАЦИЯ SAGA КОНФИГУРАЦИИ ===== + if cfg.Saga.Enabled { + if cfg.Saga.CoordinatorCount < 1 { + result.Errors = append(result.Errors, fmt.Errorf("saga.coordinator_count must be at least 1, got %d", cfg.Saga.CoordinatorCount)) + } + if cfg.Saga.CoordinatorCount < 3 { + result.Warnings = append(result.Warnings, fmt.Errorf("saga.coordinator_count is less than 3, may not be fully fault-tolerant")) + } + if cfg.Saga.MaxRetries < 0 { + result.Errors = append(result.Errors, fmt.Errorf("saga.max_retries cannot be negative, got %d", cfg.Saga.MaxRetries)) + } + if cfg.Saga.RetryBackoffMs < 0 { + result.Errors = append(result.Errors, fmt.Errorf("saga.retry_backoff_ms cannot be negative, got %d", cfg.Saga.RetryBackoffMs)) + } + if cfg.Saga.SagaTimeoutSec < 0 { + result.Errors = append(result.Errors, fmt.Errorf("saga.saga_timeout_sec cannot be negative, got %d", cfg.Saga.SagaTimeoutSec)) + } + if cfg.Saga.StuckCheckIntervalSec < 0 { + result.Errors = append(result.Errors, fmt.Errorf("saga.stuck_check_interval_sec cannot be negative, got %d", cfg.Saga.StuckCheckIntervalSec)) + } + if cfg.Saga.AsyncRecoveryWorkers < 0 { + result.Errors = append(result.Errors, fmt.Errorf("saga.async_recovery_workers cannot be negative, got %d", cfg.Saga.AsyncRecoveryWorkers)) + } + if cfg.Saga.ChannelBufferSize < 0 { + result.Errors = append(result.Errors, fmt.Errorf("saga.channel_buffer_size cannot be negative, got %d", cfg.Saga.ChannelBufferSize)) + } + } + + // ===== ВАЛИДАЦИЯ ПРОИЗВОДИТЕЛЬНОСТИ ===== + if cfg.Performance.BatchSize < 1 { + result.Errors = append(result.Errors, fmt.Errorf("batch_size must be at least 1, got %d", cfg.Performance.BatchSize)) + } + if cfg.Performance.MaxConnections < 1 { + result.Errors = append(result.Errors, fmt.Errorf("max_connections must be at least 1, got %d", cfg.Performance.MaxConnections)) + } + + // ===== ВАЛИДАЦИЯ МОНИТОРИНГА ===== + if cfg.Monitoring.TraceSampleRate < 0 || cfg.Monitoring.TraceSampleRate > 1 { + result.Errors = append(result.Errors, fmt.Errorf("trace_sample_rate must be between 0 and 1, got %f", cfg.Monitoring.TraceSampleRate)) + } + + // ===== ПРОВЕРКА КОНФЛИКТОВ ПОРТОВ ===== + // Никакие два сервиса не должны использовать один порт + if cfg.API.Port == cfg.Cluster.NodePort { + result.Errors = append(result.Errors, fmt.Errorf("API port %d conflicts with cluster node port", cfg.API.Port)) + } + if cfg.WebUI.Port == cfg.Cluster.NodePort { + result.Errors = append(result.Errors, fmt.Errorf("WebUI port %d conflicts with cluster node port", cfg.WebUI.Port)) + } + if cfg.Monitoring.MetricsPort == cfg.Cluster.NodePort { + result.Errors = append(result.Errors, fmt.Errorf("metrics port %d conflicts with cluster node port", cfg.Monitoring.MetricsPort)) + } + + // ===== ВАЛИДАЦИЯ TLS ===== + if cfg.Security.IsTLSEnabled() { + if cfg.Security.CertFile == "" { + result.Errors = append(result.Errors, fmt.Errorf("cert_file is required when TLS is enabled")) + } + if cfg.Security.KeyFile == "" { + result.Errors = append(result.Errors, fmt.Errorf("key_file is required when TLS is enabled")) + } + } + + // ===== ВАЛИДАЦИЯ СЖАТИЯ ===== + if cfg.Compression.Enabled { + switch cfg.Compression.Algorithm { + case "snappy", "lz4", "zstd": + // Поддерживаемые алгоритмы + default: + result.Errors = append(result.Errors, fmt.Errorf("unsupported compression algorithm: %s, supported: snappy, lz4, zstd", cfg.Compression.Algorithm)) + } + } + + // ===== ВАЛИДАЦИЯ WAL ===== + if cfg.WAL.RecoveryWorkers < 1 { + result.Errors = append(result.Errors, fmt.Errorf("wal.recovery_workers must be at least 1, got %d", cfg.WAL.RecoveryWorkers)) + } + if cfg.WAL.AsyncRecoveryWorkers < 1 && cfg.WAL.AsyncRecovery { + result.Warnings = append(result.Warnings, fmt.Errorf("wal.async_recovery_workers is less than 1, will use default 4")) + } + if cfg.WAL.AsyncRecoveryBuffer < 0 { + result.Errors = append(result.Errors, fmt.Errorf("wal.async_recovery_buffer cannot be negative, got %d", cfg.WAL.AsyncRecoveryBuffer)) + } + + // ===== ВАЛИДАЦИЯ MVCC ===== + if cfg.MVCC.MaxVersionsPerDoc < 0 { + result.Errors = append(result.Errors, fmt.Errorf("mvcc.max_versions_per_doc cannot be negative, got %d", cfg.MVCC.MaxVersionsPerDoc)) + } + + // ===== ВАЛИДАЦИЯ ПЛАГИНОВ ===== + if cfg.Plugins.MaxCPUTimeMs < 0 { + result.Errors = append(result.Errors, fmt.Errorf("plugins.max_cpu_time_ms cannot be negative, got %d", cfg.Plugins.MaxCPUTimeMs)) + } + if cfg.Plugins.MaxMemoryMB < 0 { + result.Errors = append(result.Errors, fmt.Errorf("plugins.max_memory_mb cannot be negative, got %d", cfg.Plugins.MaxMemoryMB)) + } + if cfg.Plugins.MaxLuaStates < 1 { + result.Warnings = append(result.Warnings, fmt.Errorf("plugins.max_lua_states is less than 1, will use default 100")) + } + + // ===== ВАЛИДАЦИЯ ОБРАТНОГО ДАВЛЕНИЯ ===== + if cfg.Backpressure.Enabled { + if cfg.Backpressure.CPUThreshold < 0 || cfg.Backpressure.CPUThreshold > 1 { + result.Errors = append(result.Errors, fmt.Errorf("backpressure.cpu_threshold must be between 0 and 1, got %f", cfg.Backpressure.CPUThreshold)) + } + if cfg.Backpressure.MemoryThreshold < 0 || cfg.Backpressure.MemoryThreshold > 1 { + result.Errors = append(result.Errors, fmt.Errorf("backpressure.memory_threshold must be between 0 and 1, got %f", cfg.Backpressure.MemoryThreshold)) + } + if cfg.Backpressure.MediumRejectProb > 100 { + result.Warnings = append(result.Warnings, fmt.Errorf("backpressure.medium_reject_prob is > 100, will be capped to 100")) + } + if cfg.Backpressure.HighRejectProb > 100 { + result.Warnings = append(result.Warnings, fmt.Errorf("backpressure.high_reject_prob is > 100, will be capped to 100")) + } + } + + // ===== ВАЛИДАЦИЯ ОГРАНИЧЕНИЙ ВРЕМЕНИ ВЫПОЛНЕНИЯ ===== + if cfg.RuntimeLimits.Enabled { + if cfg.RuntimeLimits.GlobalMaxDocSizeMB < 0 { + result.Errors = append(result.Errors, fmt.Errorf("runtime_limits.global_max_doc_size_mb cannot be negative, got %d", cfg.RuntimeLimits.GlobalMaxDocSizeMB)) + } + if cfg.RuntimeLimits.GlobalMaxCollSizeMB < 0 { + result.Errors = append(result.Errors, fmt.Errorf("runtime_limits.global_max_coll_size_mb cannot be negative, got %d", cfg.RuntimeLimits.GlobalMaxCollSizeMB)) + } + if cfg.RuntimeLimits.GlobalMaxDocsPerColl < 0 { + result.Errors = append(result.Errors, fmt.Errorf("runtime_limits.global_max_docs_per_coll cannot be negative, got %d", cfg.RuntimeLimits.GlobalMaxDocsPerColl)) + } + } + + // ===== ВАЛИДАЦИЯ АВТОМАСШТАБИРОВАНИЯ ===== + if cfg.Autoscaling.Enabled { + if cfg.Autoscaling.MinNodes < 1 { + result.Errors = append(result.Errors, fmt.Errorf("autoscaling.min_nodes must be at least 1, got %d", cfg.Autoscaling.MinNodes)) + } + if cfg.Autoscaling.MaxNodes < cfg.Autoscaling.MinNodes { + result.Errors = append(result.Errors, fmt.Errorf("autoscaling.max_nodes (%d) must be >= min_nodes (%d)", cfg.Autoscaling.MaxNodes, cfg.Autoscaling.MinNodes)) + } + if cfg.Autoscaling.ScaleUpThreshold <= 0 || cfg.Autoscaling.ScaleUpThreshold > 1 { + result.Warnings = append(result.Warnings, fmt.Errorf("autoscaling.scale_up_threshold is invalid, will use default 0.75")) + } + if cfg.Autoscaling.ScaleDownThreshold <= 0 || cfg.Autoscaling.ScaleDownThreshold >= cfg.Autoscaling.ScaleUpThreshold { + result.Warnings = append(result.Warnings, fmt.Errorf("autoscaling.scale_down_threshold should be less than scale_up_threshold")) + } + } + + // ===== ВАЛИДАЦИЯ ДВИЖКОВ ===== + if cfg.Storage.EnableCustomEngines { + defaultEngine := cfg.Storage.GetDefaultEngine() + switch defaultEngine { + case "row", "columnar", "document", "kv", "ts", "graph": + // Встроенные движки + default: + result.Warnings = append(result.Warnings, fmt.Errorf("default_engine '%s' is not a built-in engine, ensure plugin is loaded", defaultEngine)) + } + } + + // ===== ВАЛИДАЦИЯ КРОСС-ДАТАЦЕНТРОВОЙ МИГРАЦИИ ===== + if cfg.Migration.Enabled { + if cfg.Migration.Source == nil || cfg.Migration.Source.Endpoint == "" { + result.Errors = append(result.Errors, fmt.Errorf("migration.source.endpoint is required when migration is enabled")) + } + if cfg.Migration.Target == nil || cfg.Migration.Target.Endpoint == "" { + result.Errors = append(result.Errors, fmt.Errorf("migration.target.endpoint is required when migration is enabled")) + } + if cfg.Migration.Settings == nil { + result.Warnings = append(result.Warnings, fmt.Errorf("migration.settings not configured, using defaults")) + } + if cfg.Migration.Delta == nil { + result.Warnings = append(result.Warnings, fmt.Errorf("migration.delta not configured, using defaults")) + } + if cfg.Migration.Validation == nil { + result.Warnings = append(result.Warnings, fmt.Errorf("migration.validation not configured, using defaults")) + } + if cfg.Migration.Mode != "manual" && cfg.Migration.Mode != "semi_auto" && cfg.Migration.Mode != "auto" { + result.Errors = append(result.Errors, fmt.Errorf("migration.mode must be one of: manual, semi_auto, auto, got %s", cfg.Migration.Mode)) + } + if cfg.Migration.Settings != nil && cfg.Migration.Settings.BatchSize < 1 { + result.Errors = append(result.Errors, fmt.Errorf("migration.settings.batch_size must be at least 1, got %d", cfg.Migration.Settings.BatchSize)) + } + if cfg.Migration.Settings != nil && cfg.Migration.Settings.Workers < 1 { + result.Errors = append(result.Errors, fmt.Errorf("migration.settings.workers must be at least 1, got %d", cfg.Migration.Settings.Workers)) + } + if cfg.Migration.Settings != nil && cfg.Migration.Settings.MaxRetries < 0 { + result.Errors = append(result.Errors, fmt.Errorf("migration.settings.max_retries cannot be negative, got %d", cfg.Migration.Settings.MaxRetries)) + } + if cfg.Migration.Validation != nil && (cfg.Migration.Validation.SamplePercent < 0 || cfg.Migration.Validation.SamplePercent > 100) { + result.Errors = append(result.Errors, fmt.Errorf("migration.validation.sample_percent must be between 0 and 100, got %d", cfg.Migration.Validation.SamplePercent)) + } + if cfg.Migration.Delta != nil && cfg.Migration.Delta.IntervalSec < 1 { + result.Errors = append(result.Errors, fmt.Errorf("migration.delta.interval_sec must be at least 1, got %d", cfg.Migration.Delta.IntervalSec)) + } + } + + // Конфигурация считается корректной, если нет ни одной ошибки + result.Valid = len(result.Errors) == 0 + return result +}