Files
futriix/internal/config/config.go

2405 lines
102 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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
}