/* * 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"` // Настройки движков хранения } // ============================================================================= // КОНФИГУРАЦИЯ КЛАСТЕРА // ============================================================================= // 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"` // Дополнительные параметры движка } // ============================================================================= // ВСПОМОГАТЕЛЬНЫЕ СТРУКТУРЫ // ============================================================================= // 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.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)) } } // Конфигурация считается корректной, если нет ни одной ошибки result.Valid = len(result.Errors) == 0 return result }