diff --git a/internal/cluster/types.go b/internal/cluster/types.go deleted file mode 100644 index de98ac8..0000000 --- a/internal/cluster/types.go +++ /dev/null @@ -1,286 +0,0 @@ -/* - * 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/cluster/types.go -// Назначение: Общие типы данных для кластерных операций с поддержкой временных меток - -package cluster - -import ( - "fmt" - "time" -) - -// NodeInfo представляет информацию об узле для координатора -type NodeInfo struct { - ID string `json:"id"` - IP string `json:"ip"` - Port int `json:"port"` - Status string `json:"status"` - LastSeen int64 `json:"last_seen"` - JoinedAt int64 `json:"joined_at"` - UpdatedAt int64 `json:"updated_at"` - Version uint64 `json:"version"` -} - -// NOTE: ClusterStatus structure is defined in raft_coordinator.go -// to avoid duplication and ensure consistency. - -// ClusterHealth представляет информацию о здоровье кластера -type ClusterHealth struct { - Nodes map[string]*NodeHealth `json:"nodes"` - OverallScore float64 `json:"overall_score"` - Recommendations string `json:"recommendations"` - CheckedAt int64 `json:"checked_at"` -} - -// NodeHealth представляет здоровье отдельного узла -type NodeHealth struct { - Status string `json:"status"` - LatencyMs int64 `json:"latency_ms"` - LastCheck int64 `json:"last_check"` - LastSuccess int64 `json:"last_success"` - LastFailure int64 `json:"last_failure"` - FailureCount int `json:"failure_count"` -} - -// NodeRequest представляет запрос от одного узла к другому -type NodeRequest struct { - Type string `json:"type"` - Data []byte `json:"data"` - FromNode string `json:"from_node"` - RequestID string `json:"request_id"` - Timestamp int64 `json:"timestamp"` -} - -// ShardInfo представляет информацию о шарде -type ShardInfo struct { - ID string `json:"id"` - Name string `json:"name"` - Nodes []string `json:"nodes"` - LeaderNode string `json:"leader_node"` - Status string `json:"status"` - CreatedAt int64 `json:"created_at"` - UpdatedAt int64 `json:"updated_at"` - LastRebalanced int64 `json:"last_rebalanced"` - DocumentCount int64 `json:"document_count"` - SizeBytes int64 `json:"size_bytes"` -} - -// ReplicationLogEntry представляет запись в журнале репликации -type ReplicationLogEntry struct { - ID string `json:"id"` - Timestamp int64 `json:"timestamp"` - SourceNode string `json:"source_node"` - TargetNode string `json:"target_node"` - Operation string `json:"operation"` - Database string `json:"database"` - Collection string `json:"collection"` - DocumentID string `json:"document_id"` - Status string `json:"status"` - DurationMs int64 `json:"duration_ms"` - Error string `json:"error,omitempty"` - Details map[string]interface{} `json:"details,omitempty"` -} - -// ========== СТРУКТУРЫ ДЛЯ PRODUCTION-READY РЕАЛИЗАЦИИ ========== - -// ConnectionInfo содержит информацию о соединении с узлом -type ConnectionInfo struct { - NodeID string `json:"node_id"` - Address string `json:"address"` - IsHealthy bool `json:"is_healthy"` - LastUsed int64 `json:"last_used"` - Failures uint32 `json:"failures"` - ConnectedAt int64 `json:"connected_at"` -} - -// ClusterOperation представляет операцию в кластере -type ClusterOperation struct { - ID string `json:"id"` - Type string `json:"type"` // "add_node", "remove_node", "rebalance", "reshard" - Status string `json:"status"` // "pending", "in_progress", "completed", "failed" - CreatedAt int64 `json:"created_at"` - StartedAt int64 `json:"started_at"` - CompletedAt int64 `json:"completed_at"` - Details map[string]interface{} `json:"details"` - Error string `json:"error,omitempty"` -} - -// WorkerPoolStats содержит статистику пула воркеров -type WorkerPoolStats struct { - MaxWorkers int `json:"max_workers"` - ActiveTasks int32 `json:"active_tasks"` - TotalTasks uint64 `json:"total_tasks"` - FailedTasks uint64 `json:"failed_tasks"` - QueueSize int `json:"queue_size"` - QueueCapacity int `json:"queue_capacity"` -} - -// ========== МЕТОДЫ ДЛЯ NodeInfo ========== - -// NodeJoinedAt возвращает человекочитаемое время присоединения узла -func (n *NodeInfo) NodeJoinedAt() string { - if n.JoinedAt == 0 { - return "not joined" - } - return time.UnixMilli(n.JoinedAt).Format("2006-01-02 15:04:05.000") -} - -// LastSeenAt возвращает человекочитаемое время последнего контакта -func (n *NodeInfo) LastSeenAt() string { - if n.LastSeen == 0 { - return "never" - } - return time.UnixMilli(n.LastSeen).Format("2006-01-02 15:04:05.000") -} - -// GetUptime возвращает время жизни узла в кластере -func (n *NodeInfo) GetUptime() time.Duration { - if n.JoinedAt == 0 { - return 0 - } - return time.Duration(time.Now().UnixMilli()-n.JoinedAt) * time.Millisecond -} - -// IsHealthy проверяет, здоров ли узел -func (n *NodeInfo) IsHealthy() bool { - return n.Status == "active" && time.Now().UnixMilli()-n.LastSeen < 30000 -} - -// GetAddress возвращает адрес узла -func (n *NodeInfo) GetAddress() string { - return fmt.Sprintf("%s:%d", n.IP, n.Port) -} - -// ========== МЕТОДЫ ДЛЯ ShardInfo ========== - -// GetUptime возвращает время жизни шарда -func (s *ShardInfo) GetUptime() time.Duration { - if s.CreatedAt == 0 { - return 0 - } - return time.Duration(time.Now().UnixMilli()-s.CreatedAt) * time.Millisecond -} - -// IsHealthy проверяет, здоров ли шард -func (s *ShardInfo) IsHealthy() bool { - return s.Status == "active" -} - -// GetLastRebalancedStr возвращает человекочитаемое время последней ребалансировки -func (s *ShardInfo) GetLastRebalancedStr() string { - if s.LastRebalanced == 0 { - return "never" - } - return time.UnixMilli(s.LastRebalanced).Format("2006-01-02 15:04:05.000") -} - -// GetCreatedAtStr возвращает человекочитаемое время создания -func (s *ShardInfo) GetCreatedAtStr() string { - if s.CreatedAt == 0 { - return "unknown" - } - return time.UnixMilli(s.CreatedAt).Format("2006-01-02 15:04:05.000") -} - -// GetUpdatedAtStr возвращает человекочитаемое время обновления -func (s *ShardInfo) GetUpdatedAtStr() string { - if s.UpdatedAt == 0 { - return "unknown" - } - return time.UnixMilli(s.UpdatedAt).Format("2006-01-02 15:04:05.000") -} - -// GetLeaderNode возвращает лидера шарда -func (s *ShardInfo) GetLeaderNode() string { - return s.LeaderNode -} - -// GetNodeCount возвращает количество узлов в шарде -func (s *ShardInfo) GetNodeCount() int { - return len(s.Nodes) -} - -// GetReplicationFactor возвращает фактор репликации шарда -func (s *ShardInfo) GetReplicationFactor() int { - return len(s.Nodes) -} - -// ========== МЕТОДЫ ДЛЯ ReplicationLogEntry ========== - -// GetTimestampStr возвращает человекочитаемое время записи репликации -func (r *ReplicationLogEntry) GetTimestampStr() string { - if r.Timestamp == 0 { - return "unknown" - } - return time.UnixMilli(r.Timestamp).Format("2006-01-02 15:04:05.000") -} - -// IsSuccess проверяет, успешна ли операция репликации -func (r *ReplicationLogEntry) IsSuccess() bool { - return r.Status == "success" -} - -// GetDuration возвращает длительность операции -func (r *ReplicationLogEntry) GetDuration() time.Duration { - return time.Duration(r.DurationMs) * time.Millisecond -} - -// ========== МЕТОДЫ ДЛЯ ClusterHealth ========== - -// IsHealthy проверяет, здоров ли кластер в целом -func (ch *ClusterHealth) IsHealthy() bool { - return ch.OverallScore >= 80 -} - -// IsDegraded проверяет, деградирован ли кластер -func (ch *ClusterHealth) IsDegraded() bool { - return ch.OverallScore >= 50 && ch.OverallScore < 80 -} - -// IsCritical проверяет, находится ли кластер в критическом состоянии -func (ch *ClusterHealth) IsCritical() bool { - return ch.OverallScore < 50 -} - -// GetHealthyNodes возвращает количество здоровых узлов -func (ch *ClusterHealth) GetHealthyNodes() int { - count := 0 - for _, node := range ch.Nodes { - if node.Status == "active" { - count++ - } - } - return count -} - -// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ========== - -// GetTimestamp возвращает текущий timestamp в миллисекундах -func GetTimestamp() int64 { - return time.Now().UnixMilli() -} - -// FormatTimestamp форматирует timestamp в человекочитаемый вид -func FormatTimestamp(ts int64) string { - if ts == 0 { - return "never" - } - return time.UnixMilli(ts).Format("2006-01-02 15:04:05.000") -} - -// IsTimestampExpired проверяет, истёк ли timestamp -func IsTimestampExpired(ts int64, ttl time.Duration) bool { - if ts == 0 { - return true - } - return time.Now().UnixMilli()-ts > ttl.Milliseconds() -}